From f4c3b23849bd2bf5f73690c10aa7b7631a29c0eb Mon Sep 17 00:00:00 2001 From: bendo-eXX Date: Wed, 29 Jul 2026 15:29:58 +0200 Subject: [PATCH 1/5] feat(CSAF2.1): add recommendedTest_6_2_53.js --- .../recommendedTest_6_2_53.js | 10 ++---- package.json | 5 +++ rvisc.js | 32 +++++++++++++++++++ scripts/rvisc-importRegistry.js | 32 +++++++++++++++++++ tests/csaf_2_1/recommendedTest_6_2_53.js | 2 +- 5 files changed, 72 insertions(+), 9 deletions(-) create mode 100644 rvisc.js create mode 100644 scripts/rvisc-importRegistry.js diff --git a/csaf_2_1/recommendedTests/recommendedTest_6_2_53.js b/csaf_2_1/recommendedTests/recommendedTest_6_2_53.js index 65d7fb8d..433992dd 100644 --- a/csaf_2_1/recommendedTests/recommendedTest_6_2_53.js +++ b/csaf_2_1/recommendedTests/recommendedTest_6_2_53.js @@ -1,16 +1,10 @@ -import { createRequire } from 'module' import { Ajv } from 'ajv/dist/jtd.js' +import { entries } from '../../rvisc.js' const ajv = new Ajv() -const require = createRequire(import.meta.url) -const registry = - /** @type {{ entries: Array<{ system_name: string; text_pattern: string }> }} */ ( - // @ts-ignore — registry.json lives in the excluded csaf/ subtree - require('../../csaf/registry/id/registry.json') - ) /** @type {Array<{ system_name: string; text_pattern: RegExp }>} */ -const registeredIdSystems = registry.entries.map( +const registeredIdSystems = entries.map( (/** @type {{ system_name: string; text_pattern: string }} */ entry) => ({ system_name: entry.system_name, text_pattern: new RegExp(entry.text_pattern), diff --git a/package.json b/package.json index 372f7863..09fed786 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "mandatoryTests.js", "optionalTests.js", "README.md", + "rvisc.js", "schemaTests.js", "strip.js", "validate.js", @@ -100,6 +101,10 @@ "types": "./build/lib/shared/cwec.d.ts", "import": "./lib/shared/cwec.js" }, + "./rvisc.js": { + "types": "./build/rvisc.d.ts", + "import": "./rvisc.js" + }, "./lib/shared/cvss2.js": { "types": "./build/lib/shared/cvss2.d.ts", "import": "./lib/shared/cvss2.js" diff --git a/rvisc.js b/rvisc.js new file mode 100644 index 00000000..cb992c1e --- /dev/null +++ b/rvisc.js @@ -0,0 +1,32 @@ +const rvisc = { + $schema: + 'https://raw.githubusercontent.com/oasis-tcs/csaf/master/registry/id/schema/registry.schema.json', + entries: [ + { + common_name: 'OASIS Open CSAF TC GitHub Issues', + example_identifiers: ['#1217'], + published: '2026-01-28T17:45:00Z', + summary: + 'Contains identifiers for issues in the official standard repository of the OASIS Open CSAF TC.', + system_name: 'https://github.com/oasis-tcs/csaf', + text_pattern: '^#[1-9]\\d*$', + updated: '2026-01-28T17:45:00Z', + }, + { + common_name: 'EUVD IDs', + example_identifiers: ['EUVD-2026-4660'], + published: '2026-01-28T18:00:00Z', + summary: + 'Contains identifiers from the European Vulnerability Database (EUVD).', + system_name: 'https://euvd.enisa.europa.eu', + text_pattern: '^EUVD-[1-9][0-9]{3}-[0-9]{4,}$', + updated: '2026-02-06T15:35:00Z', + }, + ], + last_updated: '2026-02-06T15:35:00Z', + registry_version: 1, +} + +export default rvisc + +export const entries = rvisc.entries diff --git a/scripts/rvisc-importRegistry.js b/scripts/rvisc-importRegistry.js new file mode 100644 index 00000000..0ebf8464 --- /dev/null +++ b/scripts/rvisc-importRegistry.js @@ -0,0 +1,32 @@ +#!/usr/bin/env node + +import { writeFile, readFile } from 'node:fs/promises' +import prettier from 'prettier' + +/** + * Converts the RVISC registry (`csaf/registry/id/registry.json`, part of + * the `csaf/` git subtree and excluded from the npm package) into a plain + * ESM module (`rvisc.js`) that works in Node and in the browser. + * + * Run again after `csaf/registry/id/registry.json` was updated: + * + * node scripts/rvisc-importRegistry.js + */ + +const REGISTRY_FILE = 'csaf/registry/id/registry.json' +const OUTPUT_FILE = 'rvisc.js' + +const json = JSON.parse(await readFile(REGISTRY_FILE, 'utf-8')) + +await writeFile( + OUTPUT_FILE, + prettier.format( + `const rvisc = (${JSON.stringify( + json + )})\n\nexport default rvisc\n\nexport const entries = rvisc.entries`, + { + ...(await prettier.resolveConfig(OUTPUT_FILE)), + filepath: OUTPUT_FILE, + } + ) +) diff --git a/tests/csaf_2_1/recommendedTest_6_2_53.js b/tests/csaf_2_1/recommendedTest_6_2_53.js index 9d767128..4aaa3c59 100644 --- a/tests/csaf_2_1/recommendedTest_6_2_53.js +++ b/tests/csaf_2_1/recommendedTest_6_2_53.js @@ -5,7 +5,7 @@ describe('recommendedTest_6_2_53', function () { it('only runs on relevant documents', function () { assert.equal(recommendedTest_6_2_53({}).warnings.length, 0) }) - // + it('does not warn when ids are absent', function () { assert.equal( recommendedTest_6_2_53({ vulnerabilities: [{}] }).warnings.length, From e6a7f24deba518a147755690a4df7cc96090ae10 Mon Sep 17 00:00:00 2001 From: bendo-eXX Date: Wed, 29 Jul 2026 15:35:27 +0200 Subject: [PATCH 2/5] feat(CSAF2.1): add recommendedTest_6_2_53.js --- .../recommendedTests/recommendedTest_6_2_53.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/csaf_2_1/recommendedTests/recommendedTest_6_2_53.js b/csaf_2_1/recommendedTests/recommendedTest_6_2_53.js index 433992dd..046a5ed7 100644 --- a/csaf_2_1/recommendedTests/recommendedTest_6_2_53.js +++ b/csaf_2_1/recommendedTests/recommendedTest_6_2_53.js @@ -46,18 +46,18 @@ const validate = ajv.compile(inputSchema) /** @typedef {InputSchema['vulnerabilities'][number]} Vulnerability */ /** - * For each item in vulnerabilities[].ids[] that has a registered system_name, - * it is tested that the text matches the text_pattern from the RVISC registry. + * This implements the recommended test 6.2.53 of the CSAF 2.1 standard. * * @param {unknown} doc */ export function recommendedTest_6_2_53(doc) { - /** @type {Array<{ message: string; instancePath: string }>} */ - const warnings = [] - const context = { warnings } + const ctx = { + warnings: + /** @type {Array<{ instancePath: string; message: string }>} */ ([]), + } if (!validate(doc)) { - return context + return ctx } /** @type {Array} */ @@ -73,7 +73,7 @@ export function recommendedTest_6_2_53(doc) { if (!registeredSystem) return if (!registeredSystem.text_pattern.test(id.text)) { - warnings.push({ + ctx.warnings.push({ instancePath: `/vulnerabilities/${vulnIndex}/ids/${idIndex}/text`, message: `the text does not match the text_pattern of the registered ID system "${id.system_name}"`, }) @@ -81,5 +81,5 @@ export function recommendedTest_6_2_53(doc) { }) }) - return context + return ctx } From c53ae6d4d6c4928a8fafbc55547f73a4906e6b8a Mon Sep 17 00:00:00 2001 From: bendo-eXX Date: Mon, 3 Aug 2026 16:24:23 +0200 Subject: [PATCH 3/5] feat(CSAF2.1): register recommendedTest_6_2_53 --- README.md | 2 +- csaf_2_1/recommendedTests.js | 1 + tests/csaf_2_1/oasis.js | 1 - 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 92b52172..10b8200a 100644 --- a/README.md +++ b/README.md @@ -350,7 +350,6 @@ The following tests are not yet implemented and therefore missing: - Recommended Test 6.2.50.3 - Recommended Test 6.2.51 - Recommended Test 6.2.52 -- Recommended Test 6.2.53 - Recommended Test 6.2.54.1 - Recommended Test 6.2.54.2 - Recommended Test 6.2.54.4 @@ -501,6 +500,7 @@ export const recommendedTest_6_2_41: DocumentTest export const recommendedTest_6_2_43: DocumentTest export const recommendedTest_6_2_47: DocumentTest export const recommendedTest_6_2_48: DocumentTest +export const recommendedTest_6_2_53: DocumentTest export const recommendedTest_6_2_54_3: DocumentTest ``` diff --git a/csaf_2_1/recommendedTests.js b/csaf_2_1/recommendedTests.js index 7f91836b..cdd6cc14 100644 --- a/csaf_2_1/recommendedTests.js +++ b/csaf_2_1/recommendedTests.js @@ -42,4 +42,5 @@ export { recommendedTest_6_2_41 } from './recommendedTests/recommendedTest_6_2_4 export { recommendedTest_6_2_43 } from './recommendedTests/recommendedTest_6_2_43.js' export { recommendedTest_6_2_47 } from './recommendedTests/recommendedTest_6_2_47.js' export { recommendedTest_6_2_48 } from './recommendedTests/recommendedTest_6_2_48.js' +export { recommendedTest_6_2_53 } from './recommendedTests/recommendedTest_6_2_53.js' export { recommendedTest_6_2_54_3 } from './recommendedTests/recommendedTest_6_2_54_3.js' diff --git a/tests/csaf_2_1/oasis.js b/tests/csaf_2_1/oasis.js index 1521905f..03f6ba20 100644 --- a/tests/csaf_2_1/oasis.js +++ b/tests/csaf_2_1/oasis.js @@ -45,7 +45,6 @@ const excluded = [ '6.2.50.3', '6.2.51', '6.2.52', - '6.2.53', '6.2.54.1', '6.2.54.2', '6.2.54.4', From bfb79721a0746b375d87a1c30ee2e00a829645bf Mon Sep 17 00:00:00 2001 From: bendo-eXX Date: Mon, 10 Aug 2026 10:03:43 +0200 Subject: [PATCH 4/5] feat(csaf2.1): add header for rvisc-importRegistry.js script --- rvisc.js | 3 +++ scripts/rvisc-importRegistry.js | 8 ++++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/rvisc.js b/rvisc.js index cb992c1e..39225d54 100644 --- a/rvisc.js +++ b/rvisc.js @@ -1,3 +1,6 @@ +// This file is generated from csaf/registry/id/registry.json by scripts/rvisc-importRegistry.js. +// Do not edit by hand. + const rvisc = { $schema: 'https://raw.githubusercontent.com/oasis-tcs/csaf/master/registry/id/schema/registry.schema.json', diff --git a/scripts/rvisc-importRegistry.js b/scripts/rvisc-importRegistry.js index 0ebf8464..118a48a2 100644 --- a/scripts/rvisc-importRegistry.js +++ b/scripts/rvisc-importRegistry.js @@ -1,6 +1,6 @@ #!/usr/bin/env node -import { writeFile, readFile } from 'node:fs/promises' +import { readFile, writeFile } from 'node:fs/promises' import prettier from 'prettier' /** @@ -21,9 +21,9 @@ const json = JSON.parse(await readFile(REGISTRY_FILE, 'utf-8')) await writeFile( OUTPUT_FILE, prettier.format( - `const rvisc = (${JSON.stringify( - json - )})\n\nexport default rvisc\n\nexport const entries = rvisc.entries`, + `// This file is generated from ${REGISTRY_FILE} by scripts/rvisc-importRegistry.js. + // Do not edit by hand.\n\nconst rvisc = (${JSON.stringify(json)})\n + export default rvisc\n\nexport const entries = rvisc.entries`, { ...(await prettier.resolveConfig(OUTPUT_FILE)), filepath: OUTPUT_FILE, From 3ac6d747b0ea3dcf5287d8628c2a888741002d89 Mon Sep 17 00:00:00 2001 From: bendo-eXX Date: Thu, 13 Aug 2026 08:20:24 +0200 Subject: [PATCH 5/5] feat(csaf2.1): update to vitest --- tests/csaf_2_1/recommendedTest_6_2_53.js | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/tests/csaf_2_1/recommendedTest_6_2_53.js b/tests/csaf_2_1/recommendedTest_6_2_53.js index 4aaa3c59..18dc483e 100644 --- a/tests/csaf_2_1/recommendedTest_6_2_53.js +++ b/tests/csaf_2_1/recommendedTest_6_2_53.js @@ -1,33 +1,30 @@ -import assert from 'node:assert/strict' import { recommendedTest_6_2_53 } from '../../csaf_2_1/recommendedTests/recommendedTest_6_2_53.js' describe('recommendedTest_6_2_53', function () { it('only runs on relevant documents', function () { - assert.equal(recommendedTest_6_2_53({}).warnings.length, 0) + expect(recommendedTest_6_2_53({}).warnings.length).to.equal(0) }) it('does not warn when ids are absent', function () { - assert.equal( - recommendedTest_6_2_53({ vulnerabilities: [{}] }).warnings.length, - 0 - ) + expect( + recommendedTest_6_2_53({ vulnerabilities: [{}] }).warnings.length + ).to.equal(0) }) it('does not warn when text is absent', function () { - assert.equal( + expect( recommendedTest_6_2_53({ vulnerabilities: [ { ids: [{ system_name: 'https://example.com' }], }, ], - }).warnings.length, - 0 - ) + }).warnings.length + ).to.equal(0) }) it('does not warn when system_name is not in the registry', function () { - assert.equal( + expect( recommendedTest_6_2_53({ vulnerabilities: [ { @@ -39,8 +36,7 @@ describe('recommendedTest_6_2_53', function () { ], }, ], - }).warnings.length, - 0 - ) + }).warnings.length + ).to.equal(0) }) })