Skip to content

Commit 970c638

Browse files
committed
fix(cyclonedx): Sanitize copyrights for the CycloneDX XML report
Some characters in copyrights cannot be outputted to XML. Therefore, sanitize the copyrights content for XML. Please note that this is not optimal as this does the sanitization also for JSON output which is not required. Originally, it was intended to do a fix in the library upstream. Unfortunately, this is not trivial (see [1]). [1]: CycloneDX/cyclonedx-core-java#538 (comment) Signed-off-by: Nicolas Nobelis <[email protected]>
1 parent d19c625 commit 970c638

File tree

3 files changed

+46
-1
lines changed

3 files changed

+46
-1
lines changed

plugins/reporters/cyclonedx/src/funTest/kotlin/CycloneDxReporterFunTest.kt

+14
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import org.ossreviewtoolkit.model.OrtResult
4242
import org.ossreviewtoolkit.plugins.api.PluginConfig
4343
import org.ossreviewtoolkit.plugins.reporters.cyclonedx.CycloneDxReporter.Companion.REPORT_BASE_FILENAME
4444
import org.ossreviewtoolkit.reporter.ORT_RESULT
45+
import org.ossreviewtoolkit.reporter.ORT_RESULT_WITH_ILLEGAL_COPYRIGHTS
4546
import org.ossreviewtoolkit.reporter.ORT_RESULT_WITH_VULNERABILITIES
4647
import org.ossreviewtoolkit.reporter.ReporterInput
4748
import org.ossreviewtoolkit.utils.common.Options
@@ -99,6 +100,19 @@ class CycloneDxReporterFunTest : WordSpec({
99100
}
100101
}
101102

103+
"the expected XML file even if some copyrights contain non printable characters" {
104+
val xmlOptions = optionSingle + mapOf("output.file.formats" to "xml")
105+
106+
val bomFileResults = generateReport(ORT_RESULT_WITH_ILLEGAL_COPYRIGHTS, xmlOptions)
107+
108+
bomFileResults.shouldBeSingleton {
109+
it shouldBeSuccess { bomFile ->
110+
bomFile shouldBe aFile()
111+
bomFile shouldNotBe emptyFile()
112+
}
113+
}
114+
}
115+
102116
"be valid JSON according to schema version $defaultSchemaVersion" {
103117
val jsonOptions = optionSingle + mapOf("output.file.formats" to "json")
104118

plugins/reporters/cyclonedx/src/main/kotlin/CycloneDxReporter.kt

+5-1
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,11 @@ class CycloneDxReporter(
372372

373373
// TODO: Find a way to associate copyrights to the license they belong to, see
374374
// https://github.com/CycloneDX/cyclonedx-core-java/issues/58
375-
copyright = resolvedLicenseInfo.getCopyrights().joinToString().takeUnless { it.isEmpty() }
375+
copyright = resolvedLicenseInfo.getCopyrights().joinToString {
376+
it.filterNot { character ->
377+
character.isIdentifierIgnorable()
378+
}
379+
}.takeUnless { it.isEmpty() }
376380

377381
purl = pkg.purl + purlQualifier
378382
isModified = pkg.isModified

reporter/src/testFixtures/kotlin/TestData.kt

+27
Original file line numberDiff line numberDiff line change
@@ -427,4 +427,31 @@ val ADVISOR_WITH_VULNERABILITIES = AdvisorRun(
427427
)
428428
)
429429

430+
val SCANNER_WITH_ILLEGAL_COPYRIGHTS = scannerRunOf(
431+
Identifier("NPM:@ort:no-license-file:1.0") to listOf(
432+
ScanResult(
433+
provenance = UnknownProvenance,
434+
scanner = ScannerDetails(name = "scanner", version = "1.0", configuration = ""),
435+
summary = ScanSummary.EMPTY.copy(
436+
licenseFindings = setOf(
437+
LicenseFinding(
438+
license = "MIT",
439+
location = TextLocation("file", 1)
440+
)
441+
),
442+
copyrightFindings = setOf(
443+
CopyrightFinding(
444+
statement = "Portions created by the Initial Developer are Copyright (c) 2002 the Initial " +
445+
"Developer, holder is Tim Hudson ([email protected]), Objc, (c) Objv, " +
446+
"\u0002 \u0002 \u0001A\u0002\u0002\u0001o\u0002\u0012 AB, Copyright (c)",
447+
location = TextLocation("file", 1)
448+
)
449+
)
450+
)
451+
)
452+
)
453+
)
454+
430455
val ORT_RESULT_WITH_VULNERABILITIES = ORT_RESULT.copy(advisor = ADVISOR_WITH_VULNERABILITIES)
456+
457+
val ORT_RESULT_WITH_ILLEGAL_COPYRIGHTS = ORT_RESULT.copy(scanner = SCANNER_WITH_ILLEGAL_COPYRIGHTS)

0 commit comments

Comments
 (0)