diff --git a/plugins/reporters/cyclonedx/src/funTest/kotlin/CycloneDxReporterFunTest.kt b/plugins/reporters/cyclonedx/src/funTest/kotlin/CycloneDxReporterFunTest.kt index 640e46c8f790c..37089576c5ee6 100644 --- a/plugins/reporters/cyclonedx/src/funTest/kotlin/CycloneDxReporterFunTest.kt +++ b/plugins/reporters/cyclonedx/src/funTest/kotlin/CycloneDxReporterFunTest.kt @@ -42,6 +42,7 @@ import org.ossreviewtoolkit.model.OrtResult import org.ossreviewtoolkit.plugins.api.PluginConfig import org.ossreviewtoolkit.plugins.reporters.cyclonedx.CycloneDxReporter.Companion.REPORT_BASE_FILENAME import org.ossreviewtoolkit.reporter.ORT_RESULT +import org.ossreviewtoolkit.reporter.ORT_RESULT_WITH_ILLEGAL_COPYRIGHTS import org.ossreviewtoolkit.reporter.ORT_RESULT_WITH_VULNERABILITIES import org.ossreviewtoolkit.reporter.ReporterInput import org.ossreviewtoolkit.utils.common.Options @@ -99,6 +100,18 @@ class CycloneDxReporterFunTest : WordSpec({ } } + "the expected XML file even if some copyrights contain non printable characters" { + val jsonOptions = optionSingle + mapOf("output.file.formats" to "xml") + val bomFileResults = CycloneDxReporter().generateReport(ORT_RESULT_WITH_ILLEGAL_COPYRIGHTS, jsonOptions) + + bomFileResults.shouldBeSingleton { + it shouldBeSuccess { bomFile -> + bomFile shouldBe aFile() + bomFile shouldNotBe emptyFile() + } + } + } + "be valid JSON according to schema version $defaultSchemaVersion" { val jsonOptions = optionSingle + mapOf("output.file.formats" to "json") diff --git a/plugins/reporters/cyclonedx/src/main/kotlin/CycloneDxReporter.kt b/plugins/reporters/cyclonedx/src/main/kotlin/CycloneDxReporter.kt index dd3342dc98a4c..2ac8834e502f1 100644 --- a/plugins/reporters/cyclonedx/src/main/kotlin/CycloneDxReporter.kt +++ b/plugins/reporters/cyclonedx/src/main/kotlin/CycloneDxReporter.kt @@ -372,7 +372,13 @@ class CycloneDxReporter( // TODO: Find a way to associate copyrights to the license they belong to, see // https://github.com/CycloneDX/cyclonedx-core-java/issues/58 - copyright = resolvedLicenseInfo.getCopyrights().joinToString().takeUnless { it.isEmpty() } + + + copyright = resolvedLicenseInfo.getCopyrights().joinToString { + it.toCharArray().filterNot { character -> + character.isIdentifierIgnorable() + }.joinToString("") + } purl = pkg.purl + purlQualifier isModified = pkg.isModified diff --git a/reporter/src/testFixtures/kotlin/TestData.kt b/reporter/src/testFixtures/kotlin/TestData.kt index 946505cc845dc..3af2603c87097 100644 --- a/reporter/src/testFixtures/kotlin/TestData.kt +++ b/reporter/src/testFixtures/kotlin/TestData.kt @@ -427,4 +427,31 @@ val ADVISOR_WITH_VULNERABILITIES = AdvisorRun( ) ) +val SCANNER_WITH_ILLEGAL_COPYRIGHTS = scannerRunOf( + Identifier("NPM:@ort:no-license-file:1.0") to listOf( + ScanResult( + provenance = UnknownProvenance, + scanner = ScannerDetails(name = "scanner", version = "1.0", configuration = ""), + summary = ScanSummary.EMPTY.copy( + licenseFindings = setOf( + LicenseFinding( + license = "MIT", + location = TextLocation("file", 1) + ) + ), + copyrightFindings = setOf( + CopyrightFinding( + statement = "Portions created by the Initial Developer are Copyright (c) 2002 the Initial " + + "Developer, holder is Tim Hudson (tjh@cryptsoft.com), Objc, (c) Objv, " + + "\u0002 \u0002 \u0001A\u0002\u0002\u0001o\u0002\u0012 AB, Copyright (c)", + location = TextLocation("file", 1) + ) + ) + ) + ) + ) +) + val ORT_RESULT_WITH_VULNERABILITIES = ORT_RESULT.copy(advisor = ADVISOR_WITH_VULNERABILITIES) + +val ORT_RESULT_WITH_ILLEGAL_COPYRIGHTS = ORT_RESULT.copy(scanner = SCANNER_WITH_ILLEGAL_COPYRIGHTS)