Skip to content

perf: use indexed lookups in mandatory tests 6.1.1 and 6.1.3 - #858

Merged
bendo-eXX merged 1 commit into
secvisogram:mainfrom
stefanocke:perf/indexed-product-id-lookups
Oct 26, 2026
Merged

bendo-eXX merged 1 commit into
secvisogram:mainfrom
stefanocke:perf/indexed-product-id-lookups

Conversation

@stefanocke

Copy link
Copy Markdown
Contributor

perf: use indexed lookups in mandatory tests 6.1.1 and 6.1.3

Fixes secvisogram/csaf-validator-service#281

findMissingDefinitions (6.1.1, shared docUtils, CSAF 2.1 docProductUtils) and the
cycle search in 6.1.3 used linear find/some/findIndex lookups inside loops,
which is quadratic in the number of products. This PR replaces them with a Set
of defined ids and a Map from product id to the first relationship index
(same semantics as the former findIndex). The CSAF 2.1 variant of 6.1.1 already
uses a Set.

Results on cve-2023-39325.json (Red Hat VEX, 76 MB), released 3.0.0 vs. this branch:

Test 3.0.0 this PR same result
6.1.1 30.1 s 0.12 s yes
6.1.3 23.8 s 0.01 s yes

Results were also identical after injecting a missing product reference and a
relationship cycle into the document.

npm test (node project): all tests pass except the 6.3.8 OASIS tests, which also
fail on main locally because hunspell is not installed.

@github-actions

Copy link
Copy Markdown

Coverage after merging perf/indexed-product-id-lookups into main will be

97.54%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
cwe.js100%100%100%100%
rvisc.js100%100%100%100%
validateStrict.js75%50%100%80%21, 28
csaf_2_1
   csafAjv.js100%100%100%100%
   dateHelper.js93.10%80%100%100%63, 65
   externalRequestFree.js100%100%100%100%
   nonExternalRequestFree.js100%100%100%100%
   sharingGroup.js100%100%100%100%
csaf_2_1/informativeTests
   informativeTest_6_3_1.js100%100%100%100%
   informativeTest_6_3_11.js100%100%100%100%
   informativeTest_6_3_12.js95%75%100%100%86
   informativeTest_6_3_14.js100%100%100%100%
   informativeTest_6_3_15.js100%100%100%100%
   informativeTest_6_3_18.js100%100%100%100%
   informativeTest_6_3_2.js95.83%87.50%100%100%57
   informativeTest_6_3_20.js100%100%100%100%
   informativeTest_6_3_21_1.js100%100%100%100%
   informativeTest_6_3_21_3.js100%100%100%100%
   informativeTest_6_3_21_4.js100%100%100%100%
   informativeTest_6_3_21_5.js100%100%100%100%
   informativeTest_6_3_21_6.js100%100%100%100%
   informativeTest_6_3_21_7.js100%100%100%100%
   informativeTest_6_3_21_8.js100%100%100%100%
   informativeTest_6_3_21_9.js100%100%100%100%
   informativeTest_6_3_22.js100%100%100%100%
   informativeTest_6_3_23_1.js100%100%100%100%
   informativeTest_6_3_23_2.js100%100%100%100%
   informativeTest_6_3_24.js100%100%100%100%
   informativeTest_6_3_4.js100%100%100%100%
   informativeTest_6_3_5.js100%100%100%100%
   informativeTest_6_3_6.js100%100%100%100%
csaf_2_1/mandatoryTests
   mandatoryTest_6_1_1.js100%100%100%100%
   mandatoryTest_6_1_10.js95.65%80.95%100%100%175, 179, 226, 228
   mandatoryTest_6_1_11.js83.33%70%100%86.67%54–55, 62, 64–66, 70
   mandatoryTest_6_1_13.js98.04%87.50%100%100%137
   mandatoryTest_6_1_14.js100%100%100%100%
   mandatoryTest_6_1_2.js98.21%92.86%100%100%125
   mandatoryTest_6_1_21.js98.05%95.24%100%100%120, 269, 291
   mandatoryTest_6_1_24.js98.04%93.75%100%100%95
   mandatoryTest_6_1_25.js96.49%83.33%100%100%120, 163
   mandatoryTest_6_1_26.js100%100%100%100%
   mandatoryTest_6_1_27_11.js100%100%100%100%
   mandatoryTest_6_1_27_12.js100%100%100%100%
   mandatoryTest_6_1_27_14.js100%100%100%100%
   mandatoryTest_6_1_27_15.js100%100%100%100%
   mandatoryTest_6_1_27_16.js100%100%100%100%
   mandatoryTest_6_1_27_17.js96.97%92.86%100%100%78
   mandatoryTest_6_1_27_18.js96.97%92.86%100%100%78
   mandatoryTest_6_1_27_19.js97.22%93.75%100%100%78
   mandatoryTest_6_1_27_2.js100%100%100%100%
   mandatoryTest_6_1_27_20.js97.37%93.75%100%100%95
   mandatoryTest_6_1_27_3.js100%100%100%100%
   mandatoryTest_6_1_27_4.js100%100%100%100%
   mandatoryTest_6_1_27_5.js92.86%80%100%100%60, 62
   mandatoryTest_6_1_27_6.js96.15%87.50%100%100%54
   mandatoryTest_6_1_27_8.js97.70%93.33%100%100%122, 171
   mandatoryTest_6_1_34.js90.32%77.78%100%94.74%55–56, 77
   mandatoryTest_6_1_35.js100%100%100%100%
   mandatoryTest_6_1_36.js88.89%64.29%100%96.88%146–147, 156, 183, 185, 199
   mandatoryTest_6_1_37.js93.10%80%100%100%152, 184
   mandatoryTest_6_1_39.js100%100%100%100%
   mandatoryTest_6_1_4.js100%100%100%100%
   mandatoryTest_6_1_40.js100%100%100%100%
   mandatoryTest_6_1_41.js100%100%100%100%
   mandatoryTest_6_1_42.js98.88%95.83%100%100%223
   mandatoryTest_6_1_43.js100%100%100%100%
   mandatoryTest_6_1_44.js100%100%100%100%
   mandatoryTest_6_1_45.js100%100%100%100%
   mandatoryTest_6_1_46.js92.86%78.57%100%100%79, 83, 86
   mandatoryTest_6_1_47.js97.22%91.67%100%100%82
   mandatoryTest_6_1_49.js97.50%91.67%100%100%99
   mandatoryTest_6_1_51.js100%100%100%100%
   mandatoryTest_6_1_52.js100%100%100%100%
   mandatoryTest_6_1_53.js100%100%100%100%
   mandatoryTest_6_1_54.js85.96%85%100%85.71%54–56, 60, 74, 83–85
   mandatoryTest_6_1_55.js98.48%96.08%100%100%267, 269
   mandatoryTest_6_1_56.js100%100%100%100%
   mandatoryTest_6_1_57.js100%100%100%100%
   mandatoryTest_6_1_58.js100%100%100%100%
   mandatoryTest_6_1_6.js97.92%95.83%100%100%59
   mandatoryTest_6_1_60_1.js91.30%75%100%100%37, 41
   mandatoryTest_6_1_61.js100%100%100%100%
   mandatoryTest_6_1_62.js100%100%100%100%
   mandatoryTest_6_1_7.js100%100%100%100%
   mandatoryTest_6_1_8.js9.84%0%0%20%100, 100, 100–101, 103, 103, 108, 108, 108–110, 110, 110–112, 112, 112–113, 115, 115, 123, 68, 74, 74, 74–75, 78, 81, 81–82, 82, 82, 84, 84, 84–86, 86, 86–88, 88, 88–89, 91, 91, 96, 96, 96–98, 98, 98–99
   mandatoryTest_6_1_9.js100%100%100%100%
   mandatoryTests_6_1_38.js100%100%100%100%
csaf_2_1/mandatoryTests/shared
   docProductUtils.js86.67%68.75%100%95.83%100, 103, 129–130, 135, 170, 173, 78–79, 85, 88, 99
   wildcardUtils.js100%100%100%100%
csaf_2_1/recommendedTests
   recommendedTest_6_2_1.js96.55%87.50%100%100%77
   recommendedTest_6_2_10.js0%100%0%0%7
   recommendedTest_6_2_11.js97.30%90%100%100%59
   recommendedTest_6_2_12.js100%100%100%100%
   recommendedTest_6_2_13.js100%100%100%100%
   recommendedTest_6_2_14.js100%100%100%100%
   recommendedTest_6_2_15.js100%100%100%100%
   recommendedTest_6_2_16.js98.11%95%100%100%125
   recommendedTest_6_2_17.js0%100%0%0%7
   recommendedTest_6_2_18.js100%100%100%100%
   recommendedTest_6_2_19.js97.60%91.89%100%100%100, 210, 98
   recommendedTest_6_2_2.js100%100%100%100%
   recommendedTest_6_2_21.js100%100%100%100%
   recommendedTest_6_2_22.js100%100%100%100%
   recommendedTest_6_2_23.js94.12%80%100%100%63, 65
   recommendedTest_6_2_25.js94.87%85.71%100%100%63, 65
   recommendedTest_6_2_26.js100%100%100%100%
   recommendedTest_6_2_27.js91.38%75%100%97.14%124–125, 141, 145, 166
   recommendedTest_6_2_28.js100%100%100%100%
   recommendedTest_6_2_29.js100%100%100%100%
   recommendedTest_6_2_3.js88.89%75%80%94.44%64, 66
   recommendedTest_6_2_30.js100%100%100%100%
   recommendedTest_6_2_32.js98.11%93.75%100%100%126, 136
   recommendedTest_6_2_33.js100%100%100%100%
   recommendedTest_6_2_34.js100%100%100%100%
   recommendedTest_6_2_35.js100%100%100%100%
   recommendedTest_6_2_36.js100%100%100%100%
   recommendedTest_6_2_37.js100%100%100%100%
   recommendedTest_6_2_38.js100%100%100%100%
   recommendedTest_6_2_39_10.js100%100%100%100%
   recommendedTest_6_2_39_11.js100%100%100%100%
   recommendedTest_6_2_39_12.js100%100%100%100%
   recommendedTest_6_2_39_13.js100%100%100%100%
   recommendedTest_6_2_39_2.js96.67%91.67%100%100%78
   recommendedTest_6_2_39_3.js96.67%91.67%100%100%78
   recommendedTest_6_2_39_4.js100%100%100%100%
   recommendedTest_6_2_39_5.js100%100%100%100%
   recommendedTest_6_2_39_6.js96.77%91.67%100%100%104, 111
   recommendedTest_6_2_39_7.js100%100%100%100%
   recommendedTest_6_2_39_8.js100%100%100%100%
   recommendedTest_6_2_39_9.js100%100%100%100%
   recommendedTest_6_2_4.js100%100%100%100%
   recommendedTest_6_2_40.js96.23%90.91%100%100%110, 84
   recommendedTest_6_2_41.js100%100%100%100%
   recommendedTest_6_2_42.js99.32%98.25%100%100%158
   recommendedTest_6_2_43.js100%100%100%100%
   recommendedTest_6_2_44.js99.10%97.83%100%100%135
   recommendedTest_6_2_45.js99.12%97.92%100%100%139
   recommendedTest_6_2_47.js100%100%100%100%
   recommendedTest_6_2_48.js100%100%100%100%
   recommendedTest_6_2_49.js100%100%100%100%
   recommendedTest_6_2_5.js100%100%100%100%
   recommendedTest_6_2_52.js100%100%100%100%
   recommendedTest_6_2_53.js100%100%100%100%
   recommendedTest_6_2_54_3.js100%100%100%100%
   recommendedTest_6_2_55.js97.78%92.86%100%100%66
   recommendedTest_6_2_6.js100%100%100%100%
   recommendedTest_6_2_7.js0%100%0%0%7
   recommendedTest_6_2_8.js100%100%100%100%
   recommendedTest_6_2_9.js100%100%100%100%
csaf_2_1/recommendedTests/shared
   checkForUnsafeHashAlgorithms.js95.83%83.33%100%100%

1 similar comment
@github-actions

Copy link
Copy Markdown

Coverage after merging perf/indexed-product-id-lookups into main will be

97.54%

Coverage Report
FileStmtsBranchesFuncsLinesUncovered Lines
cwe.js100%100%100%100%
rvisc.js100%100%100%100%
validateStrict.js75%50%100%80%21, 28
csaf_2_1
   csafAjv.js100%100%100%100%
   dateHelper.js93.10%80%100%100%63, 65
   externalRequestFree.js100%100%100%100%
   nonExternalRequestFree.js100%100%100%100%
   sharingGroup.js100%100%100%100%
csaf_2_1/informativeTests
   informativeTest_6_3_1.js100%100%100%100%
   informativeTest_6_3_11.js100%100%100%100%
   informativeTest_6_3_12.js95%75%100%100%86
   informativeTest_6_3_14.js100%100%100%100%
   informativeTest_6_3_15.js100%100%100%100%
   informativeTest_6_3_18.js100%100%100%100%
   informativeTest_6_3_2.js95.83%87.50%100%100%57
   informativeTest_6_3_20.js100%100%100%100%
   informativeTest_6_3_21_1.js100%100%100%100%
   informativeTest_6_3_21_3.js100%100%100%100%
   informativeTest_6_3_21_4.js100%100%100%100%
   informativeTest_6_3_21_5.js100%100%100%100%
   informativeTest_6_3_21_6.js100%100%100%100%
   informativeTest_6_3_21_7.js100%100%100%100%
   informativeTest_6_3_21_8.js100%100%100%100%
   informativeTest_6_3_21_9.js100%100%100%100%
   informativeTest_6_3_22.js100%100%100%100%
   informativeTest_6_3_23_1.js100%100%100%100%
   informativeTest_6_3_23_2.js100%100%100%100%
   informativeTest_6_3_24.js100%100%100%100%
   informativeTest_6_3_4.js100%100%100%100%
   informativeTest_6_3_5.js100%100%100%100%
   informativeTest_6_3_6.js100%100%100%100%
csaf_2_1/mandatoryTests
   mandatoryTest_6_1_1.js100%100%100%100%
   mandatoryTest_6_1_10.js95.65%80.95%100%100%175, 179, 226, 228
   mandatoryTest_6_1_11.js83.33%70%100%86.67%54–55, 62, 64–66, 70
   mandatoryTest_6_1_13.js98.04%87.50%100%100%137
   mandatoryTest_6_1_14.js100%100%100%100%
   mandatoryTest_6_1_2.js98.21%92.86%100%100%125
   mandatoryTest_6_1_21.js98.05%95.24%100%100%120, 269, 291
   mandatoryTest_6_1_24.js98.04%93.75%100%100%95
   mandatoryTest_6_1_25.js96.49%83.33%100%100%120, 163
   mandatoryTest_6_1_26.js100%100%100%100%
   mandatoryTest_6_1_27_11.js100%100%100%100%
   mandatoryTest_6_1_27_12.js100%100%100%100%
   mandatoryTest_6_1_27_14.js100%100%100%100%
   mandatoryTest_6_1_27_15.js100%100%100%100%
   mandatoryTest_6_1_27_16.js100%100%100%100%
   mandatoryTest_6_1_27_17.js96.97%92.86%100%100%78
   mandatoryTest_6_1_27_18.js96.97%92.86%100%100%78
   mandatoryTest_6_1_27_19.js97.22%93.75%100%100%78
   mandatoryTest_6_1_27_2.js100%100%100%100%
   mandatoryTest_6_1_27_20.js97.37%93.75%100%100%95
   mandatoryTest_6_1_27_3.js100%100%100%100%
   mandatoryTest_6_1_27_4.js100%100%100%100%
   mandatoryTest_6_1_27_5.js92.86%80%100%100%60, 62
   mandatoryTest_6_1_27_6.js96.15%87.50%100%100%54
   mandatoryTest_6_1_27_8.js97.70%93.33%100%100%122, 171
   mandatoryTest_6_1_34.js90.32%77.78%100%94.74%55–56, 77
   mandatoryTest_6_1_35.js100%100%100%100%
   mandatoryTest_6_1_36.js88.89%64.29%100%96.88%146–147, 156, 183, 185, 199
   mandatoryTest_6_1_37.js93.10%80%100%100%152, 184
   mandatoryTest_6_1_39.js100%100%100%100%
   mandatoryTest_6_1_4.js100%100%100%100%
   mandatoryTest_6_1_40.js100%100%100%100%
   mandatoryTest_6_1_41.js100%100%100%100%
   mandatoryTest_6_1_42.js98.88%95.83%100%100%223
   mandatoryTest_6_1_43.js100%100%100%100%
   mandatoryTest_6_1_44.js100%100%100%100%
   mandatoryTest_6_1_45.js100%100%100%100%
   mandatoryTest_6_1_46.js92.86%78.57%100%100%79, 83, 86
   mandatoryTest_6_1_47.js97.22%91.67%100%100%82
   mandatoryTest_6_1_49.js97.50%91.67%100%100%99
   mandatoryTest_6_1_51.js100%100%100%100%
   mandatoryTest_6_1_52.js100%100%100%100%
   mandatoryTest_6_1_53.js100%100%100%100%
   mandatoryTest_6_1_54.js85.96%85%100%85.71%54–56, 60, 74, 83–85
   mandatoryTest_6_1_55.js98.48%96.08%100%100%267, 269
   mandatoryTest_6_1_56.js100%100%100%100%
   mandatoryTest_6_1_57.js100%100%100%100%
   mandatoryTest_6_1_58.js100%100%100%100%
   mandatoryTest_6_1_6.js97.92%95.83%100%100%59
   mandatoryTest_6_1_60_1.js91.30%75%100%100%37, 41
   mandatoryTest_6_1_61.js100%100%100%100%
   mandatoryTest_6_1_62.js100%100%100%100%
   mandatoryTest_6_1_7.js100%100%100%100%
   mandatoryTest_6_1_8.js9.84%0%0%20%100, 100, 100–101, 103, 103, 108, 108, 108–110, 110, 110–112, 112, 112–113, 115, 115, 123, 68, 74, 74, 74–75, 78, 81, 81–82, 82, 82, 84, 84, 84–86, 86, 86–88, 88, 88–89, 91, 91, 96, 96, 96–98, 98, 98–99
   mandatoryTest_6_1_9.js100%100%100%100%
   mandatoryTests_6_1_38.js100%100%100%100%
csaf_2_1/mandatoryTests/shared
   docProductUtils.js86.67%68.75%100%95.83%100, 103, 129–130, 135, 170, 173, 78–79, 85, 88, 99
   wildcardUtils.js100%100%100%100%
csaf_2_1/recommendedTests
   recommendedTest_6_2_1.js96.55%87.50%100%100%77
   recommendedTest_6_2_10.js0%100%0%0%7
   recommendedTest_6_2_11.js97.30%90%100%100%59
   recommendedTest_6_2_12.js100%100%100%100%
   recommendedTest_6_2_13.js100%100%100%100%
   recommendedTest_6_2_14.js100%100%100%100%
   recommendedTest_6_2_15.js100%100%100%100%
   recommendedTest_6_2_16.js98.11%95%100%100%125
   recommendedTest_6_2_17.js0%100%0%0%7
   recommendedTest_6_2_18.js100%100%100%100%
   recommendedTest_6_2_19.js97.60%91.89%100%100%100, 210, 98
   recommendedTest_6_2_2.js100%100%100%100%
   recommendedTest_6_2_21.js100%100%100%100%
   recommendedTest_6_2_22.js100%100%100%100%
   recommendedTest_6_2_23.js94.12%80%100%100%63, 65
   recommendedTest_6_2_25.js94.87%85.71%100%100%63, 65
   recommendedTest_6_2_26.js100%100%100%100%
   recommendedTest_6_2_27.js91.38%75%100%97.14%124–125, 141, 145, 166
   recommendedTest_6_2_28.js100%100%100%100%
   recommendedTest_6_2_29.js100%100%100%100%
   recommendedTest_6_2_3.js88.89%75%80%94.44%64, 66
   recommendedTest_6_2_30.js100%100%100%100%
   recommendedTest_6_2_32.js98.11%93.75%100%100%126, 136
   recommendedTest_6_2_33.js100%100%100%100%
   recommendedTest_6_2_34.js100%100%100%100%
   recommendedTest_6_2_35.js100%100%100%100%
   recommendedTest_6_2_36.js100%100%100%100%
   recommendedTest_6_2_37.js100%100%100%100%
   recommendedTest_6_2_38.js100%100%100%100%
   recommendedTest_6_2_39_10.js100%100%100%100%
   recommendedTest_6_2_39_11.js100%100%100%100%
   recommendedTest_6_2_39_12.js100%100%100%100%
   recommendedTest_6_2_39_13.js100%100%100%100%
   recommendedTest_6_2_39_2.js96.67%91.67%100%100%78
   recommendedTest_6_2_39_3.js96.67%91.67%100%100%78
   recommendedTest_6_2_39_4.js100%100%100%100%
   recommendedTest_6_2_39_5.js100%100%100%100%
   recommendedTest_6_2_39_6.js96.77%91.67%100%100%104, 111
   recommendedTest_6_2_39_7.js100%100%100%100%
   recommendedTest_6_2_39_8.js100%100%100%100%
   recommendedTest_6_2_39_9.js100%100%100%100%
   recommendedTest_6_2_4.js100%100%100%100%
   recommendedTest_6_2_40.js96.23%90.91%100%100%110, 84
   recommendedTest_6_2_41.js100%100%100%100%
   recommendedTest_6_2_42.js99.32%98.25%100%100%158
   recommendedTest_6_2_43.js100%100%100%100%
   recommendedTest_6_2_44.js99.10%97.83%100%100%135
   recommendedTest_6_2_45.js99.12%97.92%100%100%139
   recommendedTest_6_2_47.js100%100%100%100%
   recommendedTest_6_2_48.js100%100%100%100%
   recommendedTest_6_2_49.js100%100%100%100%
   recommendedTest_6_2_5.js100%100%100%100%
   recommendedTest_6_2_52.js100%100%100%100%
   recommendedTest_6_2_53.js100%100%100%100%
   recommendedTest_6_2_54_3.js100%100%100%100%
   recommendedTest_6_2_55.js97.78%92.86%100%100%66
   recommendedTest_6_2_6.js100%100%100%100%
   recommendedTest_6_2_7.js0%100%0%0%7
   recommendedTest_6_2_8.js100%100%100%100%
   recommendedTest_6_2_9.js100%100%100%100%
csaf_2_1/recommendedTests/shared
   checkForUnsafeHashAlgorithms.js95.83%83.33%100%100%

@bendo-eXX
bendo-eXX self-requested a review October 26, 2026 09:01

@bendo-eXX bendo-eXX left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@bendo-eXX
bendo-eXX merged commit 12a1914 into secvisogram:main Oct 26, 2026
7 of 8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Quadratic runtime in mandatory tests 6.1.1 and 6.1.3 makes validation of large documents take minutes instead of seconds

2 participants