diff --git a/analyzer/src/main/kotlin/managers/utils/PackageManagerDependencyHandler.kt b/analyzer/src/main/kotlin/managers/utils/PackageManagerDependencyHandler.kt index 03fa4936cca4e..99cbfe94f351c 100644 --- a/analyzer/src/main/kotlin/managers/utils/PackageManagerDependencyHandler.kt +++ b/analyzer/src/main/kotlin/managers/utils/PackageManagerDependencyHandler.kt @@ -49,7 +49,8 @@ class PackageManagerDependencyHandler( packageManager: String, definitionFile: String, scope: String, - linkage: PackageLinkage + linkage: PackageLinkage, + issues: List = emptyList() ): PackageReference = PackageReference( id = Identifier( @@ -57,7 +58,8 @@ class PackageManagerDependencyHandler( namespace = packageManager, name = definitionFile.encodeColon(), version = "$linkage@$scope" - ) + ), + issues = issues ) private fun getPackageManagerDependency(node: DependencyNode): PackageManagerDependency? = diff --git a/plugins/package-managers/spdx/src/funTest/assets/projects/synthetic/illegal-chars-external-refs/illegal_chars/package.spdx.yml b/plugins/package-managers/spdx/src/funTest/assets/projects/synthetic/illegal-chars-external-refs/illegal_chars/package.spdx.yml new file mode 100644 index 0000000000000..e1926693f3778 --- /dev/null +++ b/plugins/package-managers/spdx/src/funTest/assets/projects/synthetic/illegal-chars-external-refs/illegal_chars/package.spdx.yml @@ -0,0 +1,23 @@ +SPDXID: "SPDXRef-DOCUMENT" +spdxVersion: "SPDX-2.2" +creationInfo: + created: "2022-06-29T00:00:00Z" + creators: + - "Organization: OSS Review Toolkit" +name: "illegal_chars" +dataLicense: "CC0-1.0" +documentNamespace: "http://spdx.org/spdxdocs/example" +documentDescribes: + - "SPDXRef-Package-asio_dtls" +packages: + - SPDXID: "SPDXRef-Package-illegal_chars" # This SPDX ID contains '_' which is not allowed. + description: "A SPDX document that is in a directory characters not allowed for SPDX IDs" + copyrightText: "NONE" + filesAnalyzed: false + homepage: "https://example.com/" + licenseConcluded: "NOASSERTION" + licenseDeclared: "NOASSERTION" + originator: "Organization: Robert Bosch GmbH" + name: "illegal_chars" + downloadLocation: "https://example.com" + versionInfo: "1.0.0" diff --git a/plugins/package-managers/spdx/src/funTest/assets/projects/synthetic/illegal-chars-external-refs/project-xyz.spdx.yml b/plugins/package-managers/spdx/src/funTest/assets/projects/synthetic/illegal-chars-external-refs/project-xyz.spdx.yml new file mode 100644 index 0000000000000..3538992f5102c --- /dev/null +++ b/plugins/package-managers/spdx/src/funTest/assets/projects/synthetic/illegal-chars-external-refs/project-xyz.spdx.yml @@ -0,0 +1,29 @@ +SPDXID: "SPDXRef-DOCUMENT" +spdxVersion: "SPDX-2.2" +creationInfo: + created: "2024-07-08T18:30:22Z" + creators: + - "OSS Review Toolkit" +name: "External Ref with illegal chars" +dataLicense: "CC0-1.0" +documentNamespace: "https://spdx.org/spdxdocs/example" +documentDescribes: +- "SPDXRef-Package-illegal-chars" + +externalDocumentRefs: +- externalDocumentId: "DocumentRef-illegal_chars" # This SPDX ID contains '_' which is not allowed. + spdxDocument: "illegal_chars/package.spdx.yml" + checksum: + algorithm: "SHA1" + checksumValue: "3e3edec9f5073a7b17a9fd066e5f49ed3e41f0a2" + +packages: +- SPDXID: "SPDXRef-Package-test" + copyrightText: "NONE" + downloadLocation: "https://example.com" + filesAnalyzed: false + homepage: "NONE" + licenseConcluded: "Apache-2.0" + licenseDeclared: "Apache-2.0" + name: "Illegal Chars" + originator: "Organization: OSS Review Toolkit" diff --git a/plugins/package-managers/spdx/src/funTest/assets/projects/synthetic/subproject-conan/project-xyz.spdx.yml b/plugins/package-managers/spdx/src/funTest/assets/projects/synthetic/subproject-conan/project-xyz.spdx.yml index 8478fd35632cc..72f20e45f44dc 100644 --- a/plugins/package-managers/spdx/src/funTest/assets/projects/synthetic/subproject-conan/project-xyz.spdx.yml +++ b/plugins/package-managers/spdx/src/funTest/assets/projects/synthetic/subproject-conan/project-xyz.spdx.yml @@ -16,7 +16,7 @@ externalDocumentRefs: spdxDocument: "./subproject/subproject-with-conan-reference.spdx.yml" checksum: algorithm: "SHA1" - checksumValue: "53840294281f7d1bf401b746162da11dcf9306eb" + checksumValue: "032a087b0da8f353c03671a72179b807b4ec7eb3" packages: - SPDXID: "SPDXRef-Package-xyz" description: "Awesome product created by Example Inc." diff --git a/plugins/package-managers/spdx/src/funTest/kotlin/SpdxDocumentFileFunTest.kt b/plugins/package-managers/spdx/src/funTest/kotlin/SpdxDocumentFileFunTest.kt index 8c2a44f3ba7fc..4443fa75830f5 100644 --- a/plugins/package-managers/spdx/src/funTest/kotlin/SpdxDocumentFileFunTest.kt +++ b/plugins/package-managers/spdx/src/funTest/kotlin/SpdxDocumentFileFunTest.kt @@ -23,6 +23,7 @@ import io.kotest.core.spec.style.WordSpec import io.kotest.matchers.collections.containExactly import io.kotest.matchers.collections.containExactlyInAnyOrder import io.kotest.matchers.collections.shouldContainExactlyInAnyOrder +import io.kotest.matchers.collections.shouldHaveSingleElement import io.kotest.matchers.collections.shouldHaveSize import io.kotest.matchers.maps.haveSize import io.kotest.matchers.nulls.shouldNotBeNull @@ -255,6 +256,29 @@ class SpdxDocumentFileFunTest : WordSpec({ Identifier("SpdxDocumentFile:OpenSSL Development Team:openssl:1.1.1g") ) } + + "collect issues for subprojects using illegal SPDX identifiers" { + val projectFile = projectDir.resolve("illegal-chars-external-refs/project-xyz.spdx.yml") + val subProjectFile = projectDir.resolve("illegal-chars-external-refs/illegal_chars/package.spdx.yml") + val definitionFiles = listOf(projectFile, subProjectFile) + + val result = create("SpdxDocumentFile").resolveDependencies(definitionFiles, emptyMap()) + + val rootProject = result.projectResults[projectFile.absoluteFile]?.first() + + rootProject shouldNotBeNull { + issues shouldHaveSize 1 + issues.shouldHaveSingleElement { + val expectedMessage = Regex( + """ + .*SPDX ID 'SPDXRef-Package-illegal_chars' is only allowed to contain letters, numbers, '\.', and '-'.* + """.trimIndent() + ) + + expectedMessage.containsMatchIn(it.message) + } + } + } } }) diff --git a/plugins/package-managers/spdx/src/main/kotlin/SpdxDocumentFile.kt b/plugins/package-managers/spdx/src/main/kotlin/SpdxDocumentFile.kt index b81ac200e7742..6c790d8b29c7e 100644 --- a/plugins/package-managers/spdx/src/main/kotlin/SpdxDocumentFile.kt +++ b/plugins/package-managers/spdx/src/main/kotlin/SpdxDocumentFile.kt @@ -357,7 +357,8 @@ class SpdxDocumentFile( } internal fun getPackageManagerDependency(pkgId: String, doc: SpdxResolvedDocument): PackageReference? { - val spdxPackage = doc.getSpdxPackageForId(pkgId, mutableListOf()) ?: return null + val issues = mutableListOf() + val spdxPackage = doc.getSpdxPackageForId(pkgId, issues) ?: return null val definitionFile = doc.getDefinitionFile(pkgId) ?: return null if (spdxPackage.packageFilename.isBlank()) return null @@ -376,7 +377,8 @@ class SpdxDocumentFile( packageManager = factory.type, definitionFile = VersionControlSystem.getPathInfo(packageFile).path, scope = scope, - linkage = PackageLinkage.PROJECT_STATIC // TODO: Set linkage based on SPDX reference type. + linkage = PackageLinkage.PROJECT_STATIC, // TODO: Set linkage based on SPDX reference type. + issues = issues ) } } @@ -523,7 +525,7 @@ class SpdxDocumentFile( scopeDependencies = scopes ) - return listOf(ProjectAnalyzerResult(project, packages)) + return listOf(ProjectAnalyzerResult(project, packages, transitiveDocument.getIssuesWithoutSpdxPackage())) } /** diff --git a/plugins/package-managers/spdx/src/main/kotlin/utils/SpdxResolvedDocument.kt b/plugins/package-managers/spdx/src/main/kotlin/utils/SpdxResolvedDocument.kt index 43062c4cd6e92..8823212d11a4c 100644 --- a/plugins/package-managers/spdx/src/main/kotlin/utils/SpdxResolvedDocument.kt +++ b/plugins/package-managers/spdx/src/main/kotlin/utils/SpdxResolvedDocument.kt @@ -133,6 +133,15 @@ internal data class SpdxResolvedDocument( return pkg } + /** + * Retrieve the issues from [issuesByReferenceId] that are not associated with [any package][packagesById]. These + * issues can be related to general issues within the SPDX document. + */ + fun getIssuesWithoutSpdxPackage() = + issuesByReferenceId.mapNotNull { (id, issue) -> + if (packagesById[id] == null) issue else null + } + /** * Return the local definition file in which the package with the given [identifier] is declared. If the package * cannot be resolved or if it has not been declared in a local file, return *null*.