Skip to content
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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,6 @@ The following tests are not yet implemented and therefore missing:
- Recommended Test 6.2.40
- Recommended Test 6.2.41
- Recommended Test 6.2.42
- Recommended Test 6.2.44
- Recommended Test 6.2.45
- Recommended Test 6.2.46

Expand Down Expand Up @@ -461,6 +460,7 @@ export const recommendedTest_6_2_22: DocumentTest
export const recommendedTest_6_2_23: DocumentTest
export const recommendedTest_6_2_25: DocumentTest
export const recommendedTest_6_2_43: DocumentTest
export const recommendedTest_6_2_44: DocumentTest
```

[(back to top)](#bsi-csaf-validator-lib)
Expand Down
1 change: 1 addition & 0 deletions csaf_2_1/recommendedTests.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,4 @@ export { recommendedTest_6_2_28 } from './recommendedTests/recommendedTest_6_2_2
export { recommendedTest_6_2_29 } from './recommendedTests/recommendedTest_6_2_29.js'
export { recommendedTest_6_2_38 } from './recommendedTests/recommendedTest_6_2_38.js'
export { recommendedTest_6_2_43 } from './recommendedTests/recommendedTest_6_2_43.js'
export { recommendedTest_6_2_44 } from './recommendedTests/recommendedTest_6_2_44.js'
149 changes: 149 additions & 0 deletions csaf_2_1/recommendedTests/recommendedTest_6_2_44.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import Ajv from 'ajv/dist/jtd.js'
import { parse, validate } from 'license-expressions'
import license_information from '../../lib/license/license_information.js'

const ajv = new Ajv()

/*
This is the jtd schema that needs to match the input document so that the
test is activated. If this schema doesn't match, it normally means that the input
document does not validate against the csaf JSON schema or optional fields that
the test checks are not present.
*/
const inputSchema = /** @type {const} */ ({
additionalProperties: true,
properties: {
document: {
additionalProperties: true,
properties: {
license_expression: {
type: 'string',
},
},
},
},
})

const ABOUT_CODE_LICENSE_REF_PREFIX = 'LicenseRef-scancode-'

const DEPRECATED_ABOUT_CODE_LICENSE_KEYS = new Set(
license_information.licenses
.filter((license) => license.deprecated && license.source === 'aboutCode')
.map((license) => license.license_key)
)

const DEPRECATED_SPDX_LICENSE_KEYS = new Set(
license_information.licenses
.filter((license) => license.deprecated && license.source === 'spdx')
.map((license) => license.license_key)
)

const validateSchema = ajv.compile(inputSchema)

/**
* Check whether the license identifiers ref is a deprecated AboutCode's license
* Ignores other license inventorying entities
* @param {string} licenseRefToCheck
* @return {boolean}
*/
function isDeprecatedLicenseRef(licenseRefToCheck) {
if (!licenseRefToCheck.startsWith(ABOUT_CODE_LICENSE_REF_PREFIX)) {
return false
} else {
const licenseKey = licenseRefToCheck.substring(
ABOUT_CODE_LICENSE_REF_PREFIX.length
)
return DEPRECATED_ABOUT_CODE_LICENSE_KEYS.has(licenseKey)
}
}

/**
* Recursively checks if a parsed license expression contains deprecated licenses
*
* @param {import('license-expressions').ParsedSpdxExpression} parsedExpression - The parsed license expression
* @returns {Array<string>} all deprecated licenses
*/
function allDeprecatedLicenses(parsedExpression) {
/** @type {Array<string>} */
const deprecatedLicenses = []
// If it's a LicenseRef type directly
if (
'licenseRef' in parsedExpression &&
isDeprecatedLicenseRef(parsedExpression.licenseRef)
) {
deprecatedLicenses.push(parsedExpression.licenseRef)
}

if (
'license' in parsedExpression &&
DEPRECATED_SPDX_LICENSE_KEYS.has(parsedExpression.license)
) {
deprecatedLicenses.push(parsedExpression.license)
}

if (
'exception' in parsedExpression &&
parsedExpression.exception &&
DEPRECATED_SPDX_LICENSE_KEYS.has(parsedExpression.exception)
) {
deprecatedLicenses.push(parsedExpression.exception)
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are missing the AdditionRefs here.

// If it's a conjunction, check both sides
if ('conjunction' in parsedExpression) {
deprecatedLicenses.push(...allDeprecatedLicenses(parsedExpression.left))
deprecatedLicenses.push(...allDeprecatedLicenses(parsedExpression.right))
}

// If it's a LicenseInfo type, it doesn't contain not listed licenses
return deprecatedLicenses
}

/**
* Checks if a license expression string contains deprecated licenses
*
* @param {string} licenseToCheck - The license expression to check
* @returns {Array<string>} all deprecated licenses
*/
export function allDeprecatedInLicenseString(licenseToCheck) {
const parseResult = parse(licenseToCheck)
return allDeprecatedLicenses(parseResult)
}

/**
* It MUST be tested that all license identifier and exceptions used are not deprecated.
* This SHALL be tested for the SPDX license list and Aboutcode's "ScanCode LicenseDB".
* The test MAY be skipped for other license inventorying entities.
*
* @param {unknown} doc
*/
export function recommendedTest_6_2_44(doc) {
/*
The `ctx` variable holds the state that is accumulated during the test run and is
finally returned by the function.
*/
const ctx = {
warnings:
/** @type {Array<{ instancePath: string; message: string }>} */ ([]),
}

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

const licenseToCheck = doc.document.license_expression

if (validate(licenseToCheck).valid) {
const deprecatedLicenseIdentifiers =
allDeprecatedInLicenseString(licenseToCheck)

deprecatedLicenseIdentifiers.forEach((licenseKey) => {
ctx.warnings.push({
instancePath: '/document/license_expression',
message: `License identifier ${licenseKey} is deprecated `,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm... License identifier is a fixed term. I know that you don't mean that here as also expressions can be deprecated. Therefore, I suggest to either switch to license key or use just identifier (without license) or come up with a better suggestion.

})
})
}

return ctx
}
Loading