Skip to content

Feat: 199 informative tests csaf2 1 6.3.17 #346

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,7 @@ export const informativeTest_6_3_8: DocumentTest
export const informativeTest_6_3_9: DocumentTest
export const informativeTest_6_3_10: DocumentTest
export const informativeTest_6_3_11: DocumentTest
export const informativeTest_6_3_17: DocumentTest
```

[(back to top)](#bsi-csaf-validator-lib)
Expand Down Expand Up @@ -577,5 +578,8 @@ For the complete list of dependencies please take a look at [package.json](https
- [undici](https://undici.nodejs.org)
- [@js-joda/core](https://js-joda.github.io/js-joda/)
- [@js-joda/timezone](https://js-joda.github.io/js-joda/)
- [aboutcode licenses](https://scancode-licensedb.aboutcode.org/index.json)
- [SPDX licenses](https://raw.githubusercontent.com/spdx/license-list-data/refs/heads/main/json/licenses.json)
- [license-expressions](https://github.com/lkoskela/license-expressions)

[(back to top)](#bsi-csaf-validator-lib)
1 change: 1 addition & 0 deletions csaf_2_1/informativeTests.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ export {
} from '../informativeTests.js'
export { informativeTest_6_3_1 } from './informativeTests/informativeTest_6_3_1.js'
export { informativeTest_6_3_4 } from './informativeTests/informativeTest_6_3_4.js'
export { informativeTest_6_3_17 } from './informativeTests/informativeTest_6_3_17.js'
111 changes: 111 additions & 0 deletions csaf_2_1/informativeTests/informativeTest_6_3_17.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import Ajv from 'ajv/dist/jtd.js'

import license_information from '../../lib/license/license_information.js'
import { validate, parse } from 'license-expressions'

const ajv = new Ajv()

const CONSIDERED_LICENSE_KEYS = new Set(
license_information.licenses
.filter((license) => !license.deprecated)
.map((license) => license.license_key)
)

const inputSchema = /** @type {const} */ ({
additionalProperties: true,
properties: {
document: {
additionalProperties: true,
properties: {
license_expression: {
type: 'string',
},
},
},
},
})

const validateInput = ajv.compile(inputSchema)

/**
* Recursively checks if a parsed license expression contains any license references.
*
* @param {import('license-expressions').ParsedSpdxExpression} parsedExpression - The parsed license expression
* @returns {boolean} True if the expression contains any license references, false otherwise
*/
function containsLicenseRef(parsedExpression) {
// If it's a LicenseRef type directly
if ('licenseRef' in parsedExpression) {
return true
}

// If it's a conjunction, check both sides
if ('conjunction' in parsedExpression) {
return (
containsLicenseRef(parsedExpression.left) ||
containsLicenseRef(parsedExpression.right)
)
}

// If it's a LicenseInfo type, it doesn't contain a license reference
return false
}

/**
* Checks if a license expression contains any license references.
*
* @param {string} licenseToCheck - The license expression to check
* @returns {boolean} True if the license expression contains any license references, false otherwise
*/
export function hasLicenseRef(licenseToCheck) {
const parseResult = parse(licenseToCheck)
return containsLicenseRef(parseResult)
}

/**
* Checks if a license is valid according to SPDX or AboutCode standards.
*
* @param {string} licenseToCheck - The license expression to check
* @returns {boolean} True if the license is valid, false otherwise
*/
export function checkLicense(licenseToCheck) {
if (!licenseToCheck) {
return false
}

// First do a simple check with aboutcode and spdx license ids
// Then check whether the license is a valid SPDX license expression
// Finally check if it contains any license references
return (
(CONSIDERED_LICENSE_KEYS.has(licenseToCheck) ||
validate(licenseToCheck).valid) &&
!hasLicenseRef(licenseToCheck)
)
}

/**
* It MUST be tested that the all license identifiers and exceptions are listed either
* in the official SPDX license identifier list or AboutCode's "ScanCode LicenseDB".
* @param {unknown} doc
* @returns
*/
export function informativeTest_6_3_17(doc) {
const ctx = {
infos: /** @type {Array<{ message: string; instancePath: string }>} */ ([]),
}

if (!validateInput(doc)) {
return ctx
}

const licenseToCheck = doc.document.license_expression

if (!checkLicense(licenseToCheck)) {
ctx.infos.push({
instancePath: '/document/license_expression',
message: `Invalid license expression: '${licenseToCheck}'`,
})
}

return ctx
}
Loading