@@ -89,34 +89,47 @@ export function mandatoryTest_6_1_7(doc) {
8989 const vulnerabilities = doc . vulnerabilities
9090
9191 /**
92+ * Create a unique string for the tuple of version and source
93+ * to compare them easily
9294 * @param {string } version
93- * @param {string } source
95+ * @param {string | undefined } source
9496 */
95- function hashVersionSource ( version , source ) {
96- return JSON . stringify ( { version : version , source : source } )
97+ function createIdForVersionAndSource ( version , source ) {
98+ return JSON . stringify ( { version : version , source : source ?? '' } )
9799 }
98100
99101 /**
100102 *
101103 * @param {Metric } metric
102- * @param {string } version
103- * @param {string } source
104+ * @param {string } versionSourceId
104105 * @returns {string|null }
105106 */
106- function getSameVersionInMetric ( metric , version , source ) {
107+ function findCvssVersionWithSameVersionAndSource ( metric , versionSourceId ) {
107108 if (
108109 metric . content ?. cvss_v2 ?. version !== undefined &&
109- version === hashVersionSource ( metric . content ?. cvss_v2 . version , source )
110+ versionSourceId ===
111+ createIdForVersionAndSource (
112+ metric . content ?. cvss_v2 . version ,
113+ metric . source
114+ )
110115 ) {
111116 return metric . content ?. cvss_v2 ?. version
112117 } else if (
113118 metric . content ?. cvss_v3 ?. version !== undefined &&
114- version === hashVersionSource ( metric . content ?. cvss_v3 . version , source )
119+ versionSourceId ===
120+ createIdForVersionAndSource (
121+ metric . content ?. cvss_v3 . version ,
122+ metric . source
123+ )
115124 ) {
116125 return metric . content ?. cvss_v3 ?. version
117126 } else if (
118127 metric . content ?. cvss_v4 ?. version !== undefined &&
119- version === hashVersionSource ( metric . content ?. cvss_v4 . version , source )
128+ versionSourceId ===
129+ createIdForVersionAndSource (
130+ metric . content ?. cvss_v4 . version ,
131+ metric . source
132+ )
120133 ) {
121134 return metric . content ?. cvss_v4 ?. version
122135 } else {
@@ -126,48 +139,65 @@ export function mandatoryTest_6_1_7(doc) {
126139
127140 /**
128141 * @param {Metric } metric
129- * @param {Set<string> } versionSet
130- * @param {string } source
142+ * @param {Set<string> } versionSourceIdSet
131143 */
132- function addVersionsInMetricToSet ( metric , versionSet , source ) {
144+ function addAllVersionSourceIdsInMetricToSet ( metric , versionSourceIdSet ) {
133145 if ( metric . content ?. cvss_v2 ?. version !== undefined ) {
134- versionSet . add ( hashVersionSource ( metric . content ?. cvss_v2 . version , source ) )
146+ versionSourceIdSet . add (
147+ createIdForVersionAndSource (
148+ metric . content ?. cvss_v2 . version ,
149+ metric . source
150+ )
151+ )
135152 }
136153 if ( metric . content ?. cvss_v3 ?. version !== undefined ) {
137- versionSet . add ( hashVersionSource ( metric . content ?. cvss_v3 . version , source ) )
154+ versionSourceIdSet . add (
155+ createIdForVersionAndSource (
156+ metric . content ?. cvss_v3 . version ,
157+ metric . source
158+ )
159+ )
138160 }
139161 if ( metric . content ?. cvss_v4 ?. version !== undefined ) {
140- versionSet . add ( hashVersionSource ( metric . content ?. cvss_v4 . version , source ) )
162+ versionSourceIdSet . add (
163+ createIdForVersionAndSource (
164+ metric . content ?. cvss_v4 . version ,
165+ metric . source
166+ )
167+ )
141168 }
142169 }
143170
144- vulnerabilities . forEach ( ( vulnerability , vulnerabilityIndex ) => {
171+ vulnerabilities . forEach ( ( vulnerabilityItem , vulnerabilityIndex ) => {
145172 /** @type {Map<string, Set<string>> } */
146- const cvssVersionsByProductName = new Map ( )
173+ const versionsSourceIdSetByProduct = new Map ( )
147174
148175 /** @type {Array<Metric> | undefined } */
149- const metrics = vulnerability . metrics
176+ const metrics = vulnerabilityItem . metrics
150177 metrics ?. forEach ( ( metric , metricIndex ) => {
151178 /** @type {Array<Product> | undefined } */
152- const products = metric . products
153- const source = metric . source ? metric . source : ''
154- products ?. forEach ( ( product , productIndex ) => {
155- const versionSet = cvssVersionsByProductName . get ( product ) ?? new Set ( )
156- cvssVersionsByProductName . set ( product , versionSet )
157-
158- versionSet . forEach ( ( version ) => {
159- const sameVersion = getSameVersionInMetric ( metric , version , source )
179+ const productsOfMetric = metric . products
180+ productsOfMetric ?. forEach ( ( product , productIndex ) => {
181+ const versionSourceIdsOfProduct =
182+ versionsSourceIdSetByProduct . get ( product ) ?? new Set ( )
183+ versionsSourceIdSetByProduct . set ( product , versionSourceIdsOfProduct )
184+
185+ versionSourceIdsOfProduct . forEach ( ( versionSourceIdOfProduct ) => {
186+ const sameVersion = findCvssVersionWithSameVersionAndSource (
187+ metric ,
188+ versionSourceIdOfProduct
189+ )
160190 if ( sameVersion ) {
161191 isValid = false
162-
192+ const sourceOfMetric = metric . source ? metric . source : ''
163193 errors . push ( {
164- message : `Product is member of more than one CVSS-Vectors with the same version '${ sameVersion } ' and same source ${ source } .` ,
194+ message : `Product is member of more than one CVSS-Vectors with the same version '${ sameVersion } ' and same source ${ sourceOfMetric } .` ,
165195 instancePath : `/vulnerabilities/${ vulnerabilityIndex } /metrics/${ metricIndex } /products/${ productIndex } ` ,
166196 } )
167197 }
168198 } )
169199
170- addVersionsInMetricToSet ( metric , versionSet , source )
200+ addAllVersionSourceIdsInMetricToSet ( metric , versionSourceIdsOfProduct )
171201 } )
172202 } )
173203 } )
0 commit comments