Blob Blame History Raw
From 81ab472c579072229a61df32969cc027b0fa4b7f Mon Sep 17 00:00:00 2001
From: Evgeny Kolesnikov <ekolesni@redhat.com>
Date: Tue, 20 Oct 2020 08:55:32 +0200
Subject: [PATCH] probes/yamfilecontent: Fix field names for cases where key
 selection section is followed by a set section

$.foo[:].bar[:], $.foo[:][:] and alike.
---
 .../independent/yamlfilecontent_probe.c       | 31 ++++++++--
 .../yamlfilecontent/openshift-logging.yaml    | 12 ++++
 .../test_probes_yamlfilecontent_array.sh      |  2 +-
 .../test_probes_yamlfilecontent_array.xml     | 45 ++++++++++++++
 .../test_probes_yamlfilecontent_key.sh        |  2 +-
 .../test_probes_yamlfilecontent_key.xml       | 59 ++++++++++++++++++-
 6 files changed, 143 insertions(+), 8 deletions(-)

diff --git a/src/OVAL/probes/independent/yamlfilecontent_probe.c b/src/OVAL/probes/independent/yamlfilecontent_probe.c
index 6f18abf83..17741a240 100644
--- a/src/OVAL/probes/independent/yamlfilecontent_probe.c
+++ b/src/OVAL/probes/independent/yamlfilecontent_probe.c
@@ -206,6 +206,7 @@ static int yaml_path_query(const char *filepath, const char *yaml_path_cstr, str
 	yaml_event_type_t event_type;
 	bool sequence = false;
 	bool mapping = false;
+	bool fake_mapping = false;
 	int index = 0;
 	char *key = strdup("#");
 
@@ -224,21 +225,39 @@ static int yaml_path_query(const char *filepath, const char *yaml_path_cstr, str
 
 		if (sequence) {
 			if (event_type == YAML_SEQUENCE_END_EVENT) {
-				sequence = false;
+				if (fake_mapping) {
+					fake_mapping = false;
+					if (record && record->itemcount > 0) {
+						oscap_list_add(values, record);
+					} else {
+						// Do not collect empty records
+						oscap_htable_free0(record);
+					}
+					record = NULL;
+				} else {
+					sequence = false;
+				}
 			} else if (event_type == YAML_SEQUENCE_START_EVENT) {
-				result_error("YAML path '%s' points to a multi-dimensional structure (sequence containing another sequence)", yaml_path_cstr);
-				goto cleanup;
+				if (mapping || fake_mapping) {
+					result_error("YAML path '%s' points to a multi-dimensional structure (a map or a sequence containing other sequences)", yaml_path_cstr);
+					goto cleanup;
+				} else {
+					fake_mapping = true;
+					record = oscap_htable_new();
+				}
 			}
 		} else {
 			if (event_type == YAML_SEQUENCE_START_EVENT) {
 				sequence = true;
+				if (mapping)
+					index++;
 			}
 		}
 
 		if (mapping) {
 			if (event_type == YAML_MAPPING_END_EVENT) {
 				mapping = false;
-				if (record->itemcount > 0) {
+				if (record && record->itemcount > 0) {
 					oscap_list_add(values, record);
 				} else {
 					// Do not collect empty records
@@ -255,6 +274,10 @@ static int yaml_path_query(const char *filepath, const char *yaml_path_cstr, str
 					result_error("YAML path '%s' points to an invalid structure (map containing another map)", yaml_path_cstr);
 					goto cleanup;
 				}
+				if (fake_mapping) {
+					result_error("YAML path '%s' points to a multi-dimensional structure (two-dimensional sequence containing a map)", yaml_path_cstr);
+					goto cleanup;
+				}
 				mapping = true;
 				sequence = false;
 				index = 0;
diff --git a/tests/probes/yamlfilecontent/openshift-logging.yaml b/tests/probes/yamlfilecontent/openshift-logging.yaml
index fb6a9d8b6..581a700a3 100644
--- a/tests/probes/yamlfilecontent/openshift-logging.yaml
+++ b/tests/probes/yamlfilecontent/openshift-logging.yaml
@@ -3,6 +3,18 @@ kind: "LogForwarding"
 metadata:
   name: instance
   namespace: openshift-logging
+arrs:
+- [1, 2, 3]
+- [4, 5, 6]
+items:
+- allowHostDirVolumePlugin: false
+  defaultAddCapabilities: null
+  requiredDropCapabilities: ['KILL', 'ALL']
+  name: ['Name', 'Oth']
+- allowHostDirVolumePlugin: false
+  defaultAddCapabilities: null
+  requiredDropCapabilities: ['OPS', 'KILL', 'ALL']
+  name: ['2 Name', '2 Oth']
 spec:
   disableDefaultForwarding: true
   outputs:
diff --git a/tests/probes/yamlfilecontent/test_probes_yamlfilecontent_array.sh b/tests/probes/yamlfilecontent/test_probes_yamlfilecontent_array.sh
index fd5e47538..695a247b3 100755
--- a/tests/probes/yamlfilecontent/test_probes_yamlfilecontent_array.sh
+++ b/tests/probes/yamlfilecontent/test_probes_yamlfilecontent_array.sh
@@ -19,7 +19,7 @@ function test_probes_yamlfilecontent_array {
     $OSCAP oval eval --results $RF $DF
 
     if [ -f $RF ]; then
-        verify_results "def" $DF $RF 2 && verify_results "tst" $DF $RF 3
+        verify_results "def" $DF $RF 3 && verify_results "tst" $DF $RF 5
         ret_val=$?
     else
         ret_val=1
diff --git a/tests/probes/yamlfilecontent/test_probes_yamlfilecontent_array.xml b/tests/probes/yamlfilecontent/test_probes_yamlfilecontent_array.xml
index c05c5fbb9..77f57cd47 100644
--- a/tests/probes/yamlfilecontent/test_probes_yamlfilecontent_array.xml
+++ b/tests/probes/yamlfilecontent/test_probes_yamlfilecontent_array.xml
@@ -31,6 +31,17 @@
       </criteria>
     </definition>
 
+    <definition class="compliance" version="1" id="oval:0:def:3"> <!-- comment="true" -->
+      <metadata>
+        <title></title>
+        <description></description>
+      </metadata>
+      <criteria operator="AND">
+        <criterion comment="get_2_dim_array" test_ref="oval:0:tst:4"/>
+        <criterion comment="get_2_dim_array_set" test_ref="oval:0:tst:5"/>
+      </criteria>
+    </definition>
+
   </definitions>
 
   <tests>
@@ -49,6 +60,16 @@
       <ind-def:object object_ref="oval:0:obj:3"/>
     </ind-def:yamlfilecontent_test>
 
+    <ind-def:yamlfilecontent_test version="1" id="oval:0:tst:4" check="all" comment="true">
+      <ind-def:object object_ref="oval:0:obj:4"/>
+      <ind-def:state state_ref="oval:0:ste:3"/>
+    </ind-def:yamlfilecontent_test>
+
+    <ind-def:yamlfilecontent_test version="1" id="oval:0:tst:5" check="all" comment="true">
+      <ind-def:object object_ref="oval:0:obj:5"/>
+      <ind-def:state state_ref="oval:0:ste:3"/>
+    </ind-def:yamlfilecontent_test>
+
   </tests>
 
   <objects>
@@ -71,6 +92,18 @@
       <ind-def:yamlpath>.spec.outputs[0]</ind-def:yamlpath>
     </ind-def:yamlfilecontent_object>
 
+    <ind-def:yamlfilecontent_object version="1" id="oval:0:obj:4">
+      <ind-def:path>/tmp</ind-def:path>
+      <ind-def:filename>openshift-logging.yaml</ind-def:filename>
+      <ind-def:yamlpath>.arrs[:][:]</ind-def:yamlpath>
+    </ind-def:yamlfilecontent_object>
+
+    <ind-def:yamlfilecontent_object version="1" id="oval:0:obj:5">
+      <ind-def:path>/tmp</ind-def:path>
+      <ind-def:filename>openshift-logging.yaml</ind-def:filename>
+      <ind-def:yamlpath>.arrs</ind-def:yamlpath>
+    </ind-def:yamlfilecontent_object>
+
   </objects>
 
   <states>
@@ -87,6 +120,12 @@
       </ind-def:value>
     </ind-def:yamlfilecontent_state>
 
+    <ind-def:yamlfilecontent_state version="1" id="oval:0:ste:3">
+      <ind-def:value datatype="record">
+        <field name="#" datatype="int" var_ref="oval:0:var:3" var_check="at least one" entity_check="at least one"/>
+      </ind-def:value>
+    </ind-def:yamlfilecontent_state>
+
   </states>
 
   <variables>
@@ -99,5 +138,11 @@
       </split>
     </local_variable>
 
+    <local_variable comment="variable with three values" datatype="int" version="1" id="oval:0:var:3">
+      <split delimiter="|">
+        <literal_component>1|2|3|4|5|6</literal_component>
+      </split>
+    </local_variable>
+
   </variables>
 </oval_definitions>
diff --git a/tests/probes/yamlfilecontent/test_probes_yamlfilecontent_key.sh b/tests/probes/yamlfilecontent/test_probes_yamlfilecontent_key.sh
index fc1e0ae7e..a942552e9 100755
--- a/tests/probes/yamlfilecontent/test_probes_yamlfilecontent_key.sh
+++ b/tests/probes/yamlfilecontent/test_probes_yamlfilecontent_key.sh
@@ -19,7 +19,7 @@ function test_probes_yamlfilecontent_key {
     $OSCAP oval eval --results $RF $DF
 
     if [ -f $RF ]; then
-        verify_results "def" $DF $RF 6 && verify_results "tst" $DF $RF 7
+        verify_results "def" $DF $RF 9 && verify_results "tst" $DF $RF 10
         ret_val=$?
     else
         ret_val=1
diff --git a/tests/probes/yamlfilecontent/test_probes_yamlfilecontent_key.xml b/tests/probes/yamlfilecontent/test_probes_yamlfilecontent_key.xml
index 05757d0c8..1697b54fd 100644
--- a/tests/probes/yamlfilecontent/test_probes_yamlfilecontent_key.xml
+++ b/tests/probes/yamlfilecontent/test_probes_yamlfilecontent_key.xml
@@ -71,7 +71,7 @@
       </criteria>
     </definition>
 
-    <definition class="compliance" version="1" id="oval:0:def:7"> <!-- comment="true" -->
+    <definition class="compliance" version="1" id="oval:0:def:7"> <!-- comment="error" -->
       <metadata>
         <title></title>
         <description></description>
@@ -80,6 +80,26 @@
         <criterion comment="array_of_maps" test_ref="oval:0:tst:8"/>
       </criteria>
     </definition>
+
+    <definition class="compliance" version="1" id="oval:0:def:8"> <!-- comment="true" -->
+      <metadata>
+        <title></title>
+        <description></description>
+      </metadata>
+      <criteria operator="AND">
+        <criterion comment="array_of_maps_of_array" test_ref="oval:0:tst:9"/>
+      </criteria>
+    </definition>
+
+    <definition class="compliance" version="1" id="oval:0:def:9"> <!-- comment="true" -->
+      <metadata>
+        <title></title>
+        <description></description>
+      </metadata>
+      <criteria operator="AND">
+        <criterion comment="array_of_maps_of_array_2" test_ref="oval:0:tst:10"/>
+      </criteria>
+    </definition>
   </definitions>
 
   <tests>
@@ -116,9 +136,19 @@
       <ind-def:object object_ref="oval:0:obj:7"/>
     </ind-def:yamlfilecontent_test>
 
-    <ind-def:yamlfilecontent_test version="1" id="oval:0:tst:8" check="all" comment="true">
+    <ind-def:yamlfilecontent_test version="1" id="oval:0:tst:8" check="all" comment="error">
       <ind-def:object object_ref="oval:0:obj:8"/>
     </ind-def:yamlfilecontent_test>
+
+    <ind-def:yamlfilecontent_test version="1" id="oval:0:tst:9" check="all" comment="true">
+      <ind-def:object object_ref="oval:0:obj:9"/>
+      <ind-def:state state_ref="oval:0:ste:9"/>
+    </ind-def:yamlfilecontent_test>
+
+    <ind-def:yamlfilecontent_test version="1" id="oval:0:tst:10" check="all" comment="true">
+      <ind-def:object object_ref="oval:0:obj:10"/>
+      <ind-def:state state_ref="oval:0:ste:10"/>
+    </ind-def:yamlfilecontent_test>
   </tests>
 
   <objects>
@@ -170,6 +200,18 @@
       <ind-def:filename>openshift-logging.yaml</ind-def:filename>
       <ind-def:yamlpath>.spec.outputs</ind-def:yamlpath>
     </ind-def:yamlfilecontent_object>
+
+    <ind-def:yamlfilecontent_object version="1" id="oval:0:obj:9">
+      <ind-def:path>/tmp</ind-def:path>
+      <ind-def:filename>openshift-logging.yaml</ind-def:filename>
+      <ind-def:yamlpath>.items[:]['requiredDropCapabilities','name','q','z'][:]</ind-def:yamlpath>
+    </ind-def:yamlfilecontent_object>
+
+    <ind-def:yamlfilecontent_object version="1" id="oval:0:obj:10">
+      <ind-def:path>/tmp</ind-def:path>
+      <ind-def:filename>openshift-logging.yaml</ind-def:filename>
+      <ind-def:yamlpath>.items[:].requiredDropCapabilities[:]</ind-def:yamlpath>
+    </ind-def:yamlfilecontent_object>
   </objects>
 
   <states>
@@ -202,6 +244,19 @@
       </ind-def:value>
     </ind-def:yamlfilecontent_state>
 
+    <ind-def:yamlfilecontent_state version="1" id="oval:0:ste:9">
+      <ind-def:value datatype="record" entity_check="at least one">
+        <field name="required^drop^capabilities" operation="pattern match" entity_check="at least one">^KILL$</field>
+        <field name="name" entity_check="at least one">Name</field>
+      </ind-def:value>
+    </ind-def:yamlfilecontent_state>
+
+    <ind-def:yamlfilecontent_state version="1" id="oval:0:ste:10">
+      <ind-def:value datatype="record" entity_check="at least one">
+        <field name="#" operation="pattern match" entity_check="at least one">^KILL$</field>
+      </ind-def:value>
+    </ind-def:yamlfilecontent_state>
+
   </states>
 
 </oval_definitions>