diff --git a/pkg/sbom/io/encode.go b/pkg/sbom/io/encode.go index 64a24dbdcb07..096abd026b86 100644 --- a/pkg/sbom/io/encode.go +++ b/pkg/sbom/io/encode.go @@ -85,7 +85,8 @@ func (e *Encoder) rootComponent(r types.Report) (*core.Component, error) { root.Type = core.TypeRepository case artifact.TypeCycloneDX, artifact.TypeSPDX: // When we scan SBOM file - if r.BOM != nil { + // If SBOM file doesn't contain root component - use filesystem + if r.BOM != nil && r.BOM.Root() != nil { return r.BOM.Root(), nil } // When we scan a `json` file (meaning a file in `json` format) which was created from the SBOM file. diff --git a/pkg/sbom/io/encode_test.go b/pkg/sbom/io/encode_test.go index 06109c963d4f..80783827cee7 100644 --- a/pkg/sbom/io/encode_test.go +++ b/pkg/sbom/io/encode_test.go @@ -705,6 +705,53 @@ func TestEncoder_Encode(t *testing.T) { }, wantVulns: make(map[uuid.UUID][]core.Vulnerability), }, + { + name: "SBOM file without root component", + report: types.Report{ + SchemaVersion: 2, + ArtifactName: "report.cdx.json", + ArtifactType: artifact.TypeCycloneDX, + Results: []types.Result{ + { + Target: "Java", + Type: ftypes.Jar, + Class: types.ClassLangPkg, + Packages: []ftypes.Package{ + { + ID: "org.apache.logging.log4j:log4j-core:2.23.1", + Name: "org.apache.logging.log4j:log4j-core", + Version: "2.23.1", + Identifier: ftypes.PkgIdentifier{ + UID: "6C0AE96901617503", + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeMaven, + Namespace: "org.apache.logging.log4j", + Name: "log4j-core", + Version: "2.23.1", + }, + }, + FilePath: "log4j-core-2.23.1.jar", + }, + }, + }, + }, + BOM: newTestBOM2(t), + }, + wantComponents: map[uuid.UUID]*core.Component{ + uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000001"): fsComponent, + uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000002"): libComponent, + }, + wantRels: map[uuid.UUID][]core.Relationship{ + uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000001"): { + { + Dependency: uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000002"), + Type: core.RelationshipContains, + }, + }, + uuid.MustParse("3ff14136-e09f-4df9-80ea-000000000002"): nil, + }, + wantVulns: make(map[uuid.UUID][]core.Vulnerability), + }, { name: "json file created from SBOM file (BOM is empty)", report: types.Report{ @@ -860,3 +907,11 @@ func newTestBOM(t *testing.T) *core.BOM { bom.AddComponent(appComponent) return bom } + +// BOM without root component +func newTestBOM2(t *testing.T) *core.BOM { + uuid.SetFakeUUID(t, "2ff14136-e09f-4df9-80ea-%012d") + bom := core.NewBOM(core.Options{}) + bom.AddComponent(libComponent) + return bom +}