1+ import Ajv from 'ajv/dist/jtd.js'
2+
3+ const ajv = new Ajv ( )
4+
5+ /*
6+ This is the jtd schema that needs to match the input document so that the
7+ test is activated. If this schema doesn't match it normally means that the input
8+ document does not validate against the csaf json schema or optional fields that
9+ the test checks are not present.
10+ */
11+ const inputSchema = /** @type {const } */ ( {
12+ additionalProperties : true ,
13+ properties : {
14+ vulnerabilities : {
15+ elements : {
16+ additionalProperties : true ,
17+ optionalProperties : {
18+ product_status : {
19+ additionalProperties : true ,
20+ optionalProperties : {
21+ first_affected : { elements : { type : 'string' } } ,
22+ first_fixed : { elements : { type : 'string' } } ,
23+ fixed : { elements : { type : 'string' } } ,
24+ known_affected : { elements : { type : 'string' } } ,
25+ known_not_affected : { elements : { type : 'string' } } ,
26+ last_affected : { elements : { type : 'string' } } ,
27+ under_investigation : { elements : { type : 'string' } } ,
28+ unknown : { elements : { type : 'string' } } ,
29+ } ,
30+ } ,
31+ } ,
32+ } ,
33+ } ,
34+ } ,
35+ } )
36+
37+ const validate = ajv . compile ( inputSchema )
38+
139/**
40+ * This implements the mandatory test 6.1.6 of the CSAF 2.1 standard.
41+ *
242 * @param {any } doc
343 */
444export function mandatoryTest_6_1_6 ( doc ) {
5- /** @type {Array<{ message: string; instancePath: string }> } */
6- const errors = [ ]
7- let isValid = true
45+ /*
46+ The `ctx` variable holds the state that is accumulated during the test ran and is
47+ finally returned by the function.
48+ */
49+ const ctx = {
50+ errors :
51+ /** @type {Array<{ instancePath: string; message: string }> } */ ( [ ] ) ,
52+ isValid : true ,
53+ }
54+
55+ if ( ! validate ( doc ) ) {
56+ return ctx
57+ }
858
959 if ( Array . isArray ( doc . vulnerabilities ) ) {
1060 /** @type {Array<any> } */
@@ -61,8 +111,8 @@ export function mandatoryTest_6_1_6(doc) {
61111 const remainingGroups = groups . slice ( index + 1 )
62112 group . forEach ( ( productID ) => {
63113 if ( remainingGroups . some ( ( g ) => g . has ( productID ) ) ) {
64- isValid = false
65- errors . push ( {
114+ ctx . isValid = false
115+ ctx . errors . push ( {
66116 instancePath : `/vulnerabilities/${ vulnerabilityIndex } /product_status` ,
67117 message : `product id "${ productID } " is mentioned in contradicting product status groups` ,
68118 } )
@@ -72,5 +122,5 @@ export function mandatoryTest_6_1_6(doc) {
72122 } )
73123 }
74124
75- return { isValid , errors }
125+ return ctx
76126}
0 commit comments