Skip to content

Commit c5c978b

Browse files
committed
feat(CSAF2.1): added test to recommendedTest_6_1_6.js
1 parent 27c29b2 commit c5c978b

File tree

2 files changed

+61
-11
lines changed

2 files changed

+61
-11
lines changed

csaf_2_1/mandatoryTests/mandatoryTest_6_1_6.js

Lines changed: 56 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,60 @@
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
*/
444
export 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
}

tests/csaf_2_1/mandatoryTest_6_1_6.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ import assert from 'node:assert/strict'
22
import { mandatoryTest_6_1_6 } from '../../csaf_2_1/mandatoryTests/mandatoryTest_6_1_6.js'
33

44
describe('mandatoryTest_6_1_6', function () {
5+
it('only runs on relevant documents', function () {
6+
assert.equal(mandatoryTest_6_1_6({ document: 'mydoc' }).isValid, true)
7+
})
8+
59
it('skip the check if there is no product status', function () {
610
assert.equal(
711
mandatoryTest_6_1_6({
8-
vulnerabilities: [
9-
{
10-
metrics: [],
11-
},
12-
],
12+
vulnerabilities: [{}],
1313
}).isValid,
1414
true
1515
)

0 commit comments

Comments
 (0)