@@ -1065,13 +1065,68 @@ void xccdf_result_to_dom(struct xccdf_result *result, xmlNode *result_node, xmlD
1065
1065
}
1066
1066
xccdf_setvalue_iterator_free (setvalues );
1067
1067
1068
+ struct oscap_htable * nodes_by_rule_id = oscap_htable_new ();
1069
+
1068
1070
struct xccdf_rule_result_iterator * rule_results = xccdf_result_get_rule_results (result );
1071
+ if (use_stig_rule_id ) {
1072
+ while (xccdf_rule_result_iterator_has_more (rule_results )) {
1073
+ struct xccdf_rule_result * rule_result = xccdf_rule_result_iterator_next (rule_results );
1074
+
1075
+ const char * idref = xccdf_rule_result_get_idref (rule_result );
1076
+ if (!idref )
1077
+ continue ;
1078
+
1079
+ xccdf_test_result_type_t test_res = xccdf_rule_result_get_result (rule_result );
1080
+
1081
+ const struct xccdf_item * item = xccdf_benchmark_get_member (associated_benchmark , XCCDF_RULE , idref );
1082
+ if (!item )
1083
+ continue ;
1084
+
1085
+ struct oscap_reference_iterator * references = xccdf_item_get_references (item );
1086
+ while (oscap_reference_iterator_has_more (references )) {
1087
+ struct oscap_reference * ref = oscap_reference_iterator_next (references );
1088
+ if (strcmp (oscap_reference_get_href (ref ), DISA_STIG_VIEWER_HREF ) == 0 ) {
1089
+ const char * stig_rule_id = oscap_reference_get_title (ref );
1090
+
1091
+ xccdf_test_result_type_t other_res = (xccdf_test_result_type_t )oscap_htable_detach (nodes_by_rule_id , stig_rule_id );
1092
+ xccdf_test_result_type_t wanted_res ;
1093
+ if (other_res == 0 ) {
1094
+ wanted_res = test_res ;
1095
+ } else {
1096
+ // if one test passed, and the other didn't, the other one should win
1097
+ if (test_res == XCCDF_RESULT_PASS ) {
1098
+ wanted_res = other_res ;
1099
+ } else if (other_res == XCCDF_RESULT_PASS ) {
1100
+ wanted_res = test_res ;
1101
+ // if one had an error, that should win
1102
+ } else if (test_res == XCCDF_RESULT_ERROR || other_res == XCCDF_RESULT_ERROR ) {
1103
+ wanted_res = XCCDF_RESULT_ERROR ;
1104
+ // next prio: failures
1105
+ } else if (test_res == XCCDF_RESULT_FAIL || other_res == XCCDF_RESULT_FAIL ) {
1106
+ wanted_res = XCCDF_RESULT_FAIL ;
1107
+ // next prio: unknown
1108
+ } else if (test_res == XCCDF_RESULT_UNKNOWN || other_res == XCCDF_RESULT_UNKNOWN ) {
1109
+ wanted_res = XCCDF_RESULT_UNKNOWN ;
1110
+ // otherwise, just pick the lower one (more or less arbitrarily)
1111
+ } else {
1112
+ wanted_res = (test_res < other_res ) ? test_res : other_res ;
1113
+ }
1114
+ }
1115
+ oscap_htable_add (nodes_by_rule_id , stig_rule_id , (void * )wanted_res );
1116
+ }
1117
+ }
1118
+ oscap_reference_iterator_free (references );
1119
+ }
1120
+ xccdf_rule_result_iterator_reset (rule_results );
1121
+ }
1069
1122
while (xccdf_rule_result_iterator_has_more (rule_results )) {
1070
1123
struct xccdf_rule_result * rule_result = xccdf_rule_result_iterator_next (rule_results );
1071
- xccdf_rule_result_to_dom (rule_result , doc , result_node , version_info , associated_benchmark , use_stig_rule_id );
1124
+ xccdf_rule_result_to_dom (rule_result , doc , result_node , version_info , associated_benchmark , use_stig_rule_id , nodes_by_rule_id );
1072
1125
}
1073
1126
xccdf_rule_result_iterator_free (rule_results );
1074
1127
1128
+ oscap_htable_free0 (nodes_by_rule_id );
1129
+
1075
1130
struct xccdf_score_iterator * scores = xccdf_result_get_scores (result );
1076
1131
while (xccdf_score_iterator_has_more (scores )) {
1077
1132
struct xccdf_score * score = xccdf_score_iterator_next (scores );
@@ -1221,36 +1276,39 @@ xmlNode *xccdf_target_identifier_to_dom(const struct xccdf_target_identifier *ti
1221
1276
return target_idref_node ;
1222
1277
}
1223
1278
}
1224
-
1225
- xmlNode * xccdf_rule_result_to_dom (struct xccdf_rule_result * result , xmlDoc * doc , xmlNode * parent , const struct xccdf_version_info * version_info , struct xccdf_benchmark * benchmark , bool use_stig_rule_id )
1279
+ static void _xccdf_rule_result_to_dom_idref ( struct xccdf_rule_result * result , xmlDoc * doc , xmlNode * parent , const struct xccdf_version_info * version_info , struct xccdf_benchmark * benchmark , const char * idref );
1280
+ void xccdf_rule_result_to_dom (struct xccdf_rule_result * result , xmlDoc * doc , xmlNode * parent , const struct xccdf_version_info * version_info , struct xccdf_benchmark * benchmark , bool use_stig_rule_id , struct oscap_htable * nodes_by_rule_id )
1226
1281
{
1227
1282
const char * idref = xccdf_rule_result_get_idref (result );
1228
1283
if (use_stig_rule_id ) {
1229
1284
// Don't output rules with no stig ids
1230
1285
if (!idref || !benchmark )
1231
- return NULL ;
1286
+ return ;
1232
1287
1233
- struct xccdf_item * item = xccdf_benchmark_get_member (benchmark , XCCDF_RULE , idref );
1288
+ const struct xccdf_item * item = xccdf_benchmark_get_member (benchmark , XCCDF_RULE , idref );
1234
1289
if (!item )
1235
- return NULL ;
1290
+ return ;
1236
1291
1237
- const char * stig_rule_id = NULL ;
1238
- struct oscap_reference_iterator * references = xccdf_item_get_references (XRULE (item ));
1292
+ struct oscap_reference_iterator * references = xccdf_item_get_references (item );
1239
1293
while (oscap_reference_iterator_has_more (references )) {
1240
1294
struct oscap_reference * ref = oscap_reference_iterator_next (references );
1241
1295
if (strcmp (oscap_reference_get_href (ref ), DISA_STIG_VIEWER_HREF ) == 0 ) {
1242
- stig_rule_id = oscap_reference_get_title (ref );
1243
- break ;
1296
+ const char * stig_rule_id = oscap_reference_get_title (ref );
1297
+
1298
+ xccdf_test_result_type_t expected_res = (xccdf_test_result_type_t )oscap_htable_get (nodes_by_rule_id , stig_rule_id );
1299
+ xccdf_test_result_type_t test_res = xccdf_rule_result_get_result (result );
1300
+ if (expected_res == test_res ) {
1301
+ oscap_htable_detach (nodes_by_rule_id , stig_rule_id );
1302
+ _xccdf_rule_result_to_dom_idref (result , doc , parent , version_info , benchmark , stig_rule_id );
1303
+ }
1244
1304
}
1245
1305
}
1246
1306
oscap_reference_iterator_free (references );
1247
-
1248
- if (!stig_rule_id )
1249
- return NULL ;
1250
-
1251
- idref = stig_rule_id ;
1307
+ } else {
1308
+ _xccdf_rule_result_to_dom_idref (result , doc , parent , version_info , benchmark , idref );
1252
1309
}
1253
-
1310
+ }
1311
+ static void _xccdf_rule_result_to_dom_idref (struct xccdf_rule_result * result , xmlDoc * doc , xmlNode * parent , const struct xccdf_version_info * version_info , struct xccdf_benchmark * benchmark , const char * idref ) {
1254
1312
xmlNs * ns_xccdf = lookup_xccdf_ns (doc , parent , version_info );
1255
1313
1256
1314
xmlNode * result_node = xmlNewTextChild (parent , ns_xccdf , BAD_CAST "rule-result" , NULL );
@@ -1343,8 +1401,6 @@ xmlNode *xccdf_rule_result_to_dom(struct xccdf_rule_result *result, xmlDoc *doc,
1343
1401
xccdf_check_to_dom (check , doc , result_node , version_info );
1344
1402
}
1345
1403
xccdf_check_iterator_free (checks );
1346
-
1347
- return result_node ;
1348
1404
}
1349
1405
1350
1406
bool xccdf_rule_result_override (struct xccdf_rule_result * rule_result , xccdf_test_result_type_t new_result , const char * waiver_time , const char * authority , struct oscap_text * remark )
0 commit comments