Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(sbom): fix panic when scanning SBOM file without root component into SBOM format #7051

Merged
5 changes: 4 additions & 1 deletion pkg/sbom/io/encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,10 @@ func (e *Encoder) rootComponent(r types.Report) (*core.Component, error) {
case artifact.TypeCycloneDX, artifact.TypeSPDX:
// When we scan SBOM file
if r.BOM != nil {
return r.BOM.Root(), nil
// If SBOM file doesn't contain root component - use filesystem
if bomRoot := r.BOM.Root(); bomRoot != nil {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if bomRoot := r.BOM.Root(); bomRoot != nil {
if r.BOM != nil && rBOM.Root() != nil {
return r.BOM.Root(), nil

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated in c4c413a

return bomRoot, nil
}
}
// When we scan a `json` file (meaning a file in `json` format) which was created from the SBOM file.
// e.g. for use in `convert` mode.
Expand Down
62 changes: 62 additions & 0 deletions pkg/sbom/io/encode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"testing"

"github.com/package-url/packageurl-go"
"github.com/samber/lo"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

Expand Down Expand Up @@ -581,6 +582,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",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it needed? UID is not used in encode.go for now.

Copy link
Contributor Author

@DmitriyLewen DmitriyLewen Jun 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh.. right. Thanks!
It looks like I accidentally copied Report for testcase from PR where we add UID 😄

Removed in 9afe959

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"): libComponentWithUID(),
},
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{
Expand Down Expand Up @@ -728,9 +776,23 @@ var (
}
)

func libComponentWithUID() *core.Component {
component := lo.FromPtr(libComponent)
component.PkgIdentifier.UID = "6C0AE96901617503"
return lo.ToPtr(component)
}

func newTestBOM(t *testing.T) *core.BOM {
uuid.SetFakeUUID(t, "2ff14136-e09f-4df9-80ea-%012d")
bom := core.NewBOM(core.Options{})
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
}