From 5f69937cc6986912925a8a1b0801810ea850ba79 Mon Sep 17 00:00:00 2001 From: DmitriyLewen <91113035+DmitriyLewen@users.noreply.github.com> Date: Wed, 27 Mar 2024 13:07:12 +0600 Subject: [PATCH] fix(sbom): fix error when parent of SPDX Relationships is not a package. (#6399) --- pkg/sbom/core/bom.go | 10 +++- .../with-file-as-relationship-parent.json | 54 +++++++++++++++++++ pkg/sbom/spdx/unmarshal.go | 12 ++++- pkg/sbom/spdx/unmarshal_test.go | 5 ++ 4 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 pkg/sbom/spdx/testdata/happy/with-file-as-relationship-parent.json diff --git a/pkg/sbom/core/bom.go b/pkg/sbom/core/bom.go index 54755a81e6c8..893796a0fe0d 100644 --- a/pkg/sbom/core/bom.go +++ b/pkg/sbom/core/bom.go @@ -238,12 +238,20 @@ func (b *BOM) AddComponent(c *Component) { } func (b *BOM) AddRelationship(parent, child *Component, relationshipType RelationshipType) { + // Check the wrong parent to avoid `panic` + if parent == nil { + return + } if parent.id == uuid.Nil { b.AddComponent(parent) } if child == nil { - b.relationships[parent.id] = nil // Meaning no dependencies + // It is possible that `relationships` already contains this parent. + // Check this to avoid overwriting. + if _, ok := b.relationships[parent.id]; !ok { + b.relationships[parent.id] = nil // Meaning no dependencies + } return } diff --git a/pkg/sbom/spdx/testdata/happy/with-file-as-relationship-parent.json b/pkg/sbom/spdx/testdata/happy/with-file-as-relationship-parent.json new file mode 100644 index 000000000000..798e75d0a52a --- /dev/null +++ b/pkg/sbom/spdx/testdata/happy/with-file-as-relationship-parent.json @@ -0,0 +1,54 @@ +{ + "files": [ + { + "fileName": "./Modules/Microsoft.PowerShell.PSResourceGet/_manifest/spdx_2.2/manifest.spdx.json", + "SPDXID": "SPDXRef-File--Modules-Microsoft.PowerShell.PSResourceGet--manifest-spdx-2.2-manifest.spdx.json-2B9FB98F5CA97DC84FD382A8F8E68F663C003362", + "checksums": [ + { + "algorithm": "SHA256", + "checksumValue": "4201b0989938842ef8c11a006184e0b1466bd7f9bb2af61d89a4c8318d43466e" + }, + { + "algorithm": "SHA1", + "checksumValue": "2b9fb98f5ca97dc84fd382a8f8e68f663c003362" + } + ], + "licenseConcluded": "NOASSERTION", + "licenseInfoInFiles": [ + "NOASSERTION" + ], + "copyrightText": "NOASSERTION", + "fileTypes": [ + "SPDX" + ] + } + ], + "externalDocumentRefs": [], + "relationships": [ + { + "relationshipType": "DESCRIBES", + "relatedSpdxElement": "SPDXRef-RootPackage", + "spdxElementId": "SPDXRef-DOCUMENT" + }, + { + "relationshipType": "DESCRIBED_BY", + "relatedSpdxElement": "SPDXRef-DOCUMENT", + "spdxElementId": "SPDXRef-File--Modules-Microsoft.PowerShell.PSResourceGet--manifest-spdx-2.2-manifest.spdx.json-2B9FB98F5CA97DC84FD382A8F8E68F663C003362" + } + ], + "spdxVersion": "SPDX-2.2", + "dataLicense": "CC0-1.0", + "SPDXID": "SPDXRef-DOCUMENT", + "name": "PowerShell Linux Arm32 7.5.0-preview.2", + "documentNamespace": "https://sbom.microsoft/1:2QSF7qZlbE-F7QrUJlEo7g:pHp_nUFvDUijZ4LrJ4RhoQ/696:458654/PowerShell%20Linux%20Arm32:7.5.0-preview.2:pDkyTHXmgUOdzSXIq9CiqA", + "creationInfo": { + "created": "2024-02-22T00:43:53Z", + "creators": [ + "Organization: Microsoft", + "Tool: Microsoft.SBOMTool-2.2.3" + ] + }, + "documentDescribes": [ + "SPDXRef-RootPackage" + ] +} \ No newline at end of file diff --git a/pkg/sbom/spdx/unmarshal.go b/pkg/sbom/spdx/unmarshal.go index 14b34c1c0caf..bda18c16980a 100644 --- a/pkg/sbom/spdx/unmarshal.go +++ b/pkg/sbom/spdx/unmarshal.go @@ -87,8 +87,16 @@ func (s *SPDX) unmarshal(spdxDocument *spdx.Document) error { continue } - compA := components[rel.RefA.ElementRefID] - compB := components[rel.RefB.ElementRefID] + compA, ok := components[rel.RefA.ElementRefID] + if !ok { // Skip if parent is not Package + continue + } + + compB, ok := components[rel.RefB.ElementRefID] + if !ok { // Skip if child is not Package + continue + } + s.BOM.AddRelationship(compA, compB, s.parseRelationshipType(rel.Relationship)) } diff --git a/pkg/sbom/spdx/unmarshal_test.go b/pkg/sbom/spdx/unmarshal_test.go index f65294020728..73f7d2dc934f 100644 --- a/pkg/sbom/spdx/unmarshal_test.go +++ b/pkg/sbom/spdx/unmarshal_test.go @@ -314,6 +314,11 @@ func TestUnmarshaler_Unmarshal(t *testing.T) { }, }, }, + { + name: "happy path with file as parent of relationship", + inputFile: "testdata/happy/with-file-as-relationship-parent.json", + want: types.SBOM{}, + }, { name: "happy path only os component", inputFile: "testdata/happy/os-only-bom.json",