-
Notifications
You must be signed in to change notification settings - Fork 8
/
mandatoryTest_6_1_27_9.js
129 lines (113 loc) · 3.95 KB
/
mandatoryTest_6_1_27_9.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/**
* @typedef {object} VulnerabilityProductStatus
* @property {unknown} known_not_affected
*/
/**
* @typedef {object} Vulnerability
* @property {unknown} flags
* @property {VulnerabilityProductStatus} [product_status]
* @property {unknown} threats
*/
/**
* @param {any} doc
*/
export default function mandatoryTest_6_1_27_9(doc) {
/** @type {Array<{ message: string; instancePath: string }>} */
const errors = []
let isValid = true
/** @type {unknown} */
const vulnerabilities = doc.vulnerabilities
if (doc.document?.category !== 'csaf_vex' || !Array.isArray(vulnerabilities))
return { errors, isValid }
vulnerabilities.forEach(
(
/**
* @type {Vulnerability | null} vulnerability
*/
vulnerability,
vulnerabilityIndex
) => {
const productStatus = vulnerability?.product_status
if (
!vulnerability ||
!productStatus ||
!Array.isArray(productStatus.known_not_affected)
)
return
productStatus.known_not_affected.forEach((productId, productIdIndex) => {
/**
* @typedef {object} Threat
* @property {unknown} category
* @property {unknown} group_ids
* @property {unknown} product_ids
*/
/** @type {(Threat | null)[]} */
const threats = Array.isArray(vulnerability.threats)
? vulnerability.threats
: []
const hasMatchingThreat = threats.some((threat) => {
if (!threat || threat.category !== 'impact') return false
const threatHasMatchingProduct =
Array.isArray(threat.product_ids) &&
threat.product_ids.includes(productId)
if (threatHasMatchingProduct) return true
const productGroups = doc.product_tree?.product_groups
const threatHasMatchingProductGroup =
Array.isArray(threat.group_ids) &&
Array.isArray(productGroups) &&
threat.group_ids.some((groupId) => {
/** @type {{ product_ids: unknown } | undefined} */
const group = productGroups.find((g) => g.group_id === groupId)
return (
group &&
Array.isArray(group.product_ids) &&
group.product_ids.includes(productId)
)
})
if (threatHasMatchingProductGroup) return true
return false
})
/**
* @typedef {object} Flag
* @property {unknown} label
* @property {unknown} group_ids
* @property {unknown} product_ids
*/
/** @type {(Flag | null)[]} */
const flags = Array.isArray(vulnerability.flags)
? vulnerability.flags
: []
const hasMatchingFlag = flags.some((flag) => {
if (!flag) return false
const flagHasMatchingProduct =
Array.isArray(flag.product_ids) &&
flag.product_ids.includes(productId)
if (flagHasMatchingProduct) return true
const productGroups = doc.product_tree?.product_groups
const flagHasMatchingProductGroup =
Array.isArray(flag.group_ids) &&
Array.isArray(productGroups) &&
flag.group_ids.some((groupId) => {
/** @type {{ product_ids: unknown } | undefined} */
const group = productGroups.find((g) => g.group_id === groupId)
return (
group &&
Array.isArray(group.product_ids) &&
group.product_ids.includes(productId)
)
})
if (flagHasMatchingProductGroup) return true
return false
})
if (!hasMatchingThreat && !hasMatchingFlag) {
isValid = false
errors.push({
instancePath: `/vulnerabilities/${vulnerabilityIndex}/product_status/known_not_affected/${productIdIndex}`,
message: 'no suitable impact statement found',
})
}
})
}
)
return { errors, isValid }
}