diff --git a/pkg/fanal/analyzer/sbom/sbom.go b/pkg/fanal/analyzer/sbom/sbom.go index 55768cff3a9b..20a069d52961 100644 --- a/pkg/fanal/analyzer/sbom/sbom.go +++ b/pkg/fanal/analyzer/sbom/sbom.go @@ -4,6 +4,7 @@ import ( "context" "os" "path" + "slices" "strings" "golang.org/x/xerrors" @@ -51,6 +52,14 @@ func (a sbomAnalyzer) Analyze(ctx context.Context, input analyzer.AnalysisInput) handleBitnamiImages(path.Dir(input.FilePath), bom) } + // FilePath for apps with aggregatingTypes is empty. + // Set the SBOM file path as Application.FilePath to correctly overwrite applications when merging layers. + for i, app := range bom.Applications { + if slices.Contains(ftypes.AggregatingTypes, app.Type) && app.FilePath == "" { + bom.Applications[i].FilePath = input.FilePath + } + } + return &analyzer.AnalysisResult{ PackageInfos: bom.Packages, Applications: bom.Applications, diff --git a/pkg/fanal/analyzer/sbom/sbom_test.go b/pkg/fanal/analyzer/sbom/sbom_test.go index 542a7f50addd..3e0f252b17d7 100644 --- a/pkg/fanal/analyzer/sbom/sbom_test.go +++ b/pkg/fanal/analyzer/sbom/sbom_test.go @@ -28,7 +28,34 @@ func Test_sbomAnalyzer_Analyze(t *testing.T) { want: &analyzer.AnalysisResult{ Applications: []types.Application{ { - Type: types.Jar, + Type: types.Bitnami, + FilePath: "opt/bitnami/elasticsearch", + Packages: types.Packages{ + { + ID: "elasticsearch@8.9.1", + Name: "elasticsearch", + Version: "8.9.1", + Arch: "arm64", + Licenses: []string{"Elastic-2.0"}, + Identifier: types.PkgIdentifier{ + PURL: &packageurl.PackageURL{ + Type: packageurl.TypeBitnami, + Name: "elasticsearch", + Version: "8.9.1", + Qualifiers: packageurl.Qualifiers{ + { + Key: "arch", + Value: "arm64", + }, + }, + }, + }, + }, + }, + }, + { + Type: types.Jar, + FilePath: "opt/bitnami/elasticsearch/.spdx-elasticsearch.spdx", Packages: types.Packages{ { ID: "co.elastic.apm:apm-agent:1.36.0", @@ -88,32 +115,6 @@ func Test_sbomAnalyzer_Analyze(t *testing.T) { }, }, }, - { - Type: types.Bitnami, - FilePath: "opt/bitnami/elasticsearch", - Packages: types.Packages{ - { - ID: "elasticsearch@8.9.1", - Name: "elasticsearch", - Version: "8.9.1", - Arch: "arm64", - Licenses: []string{"Elastic-2.0"}, - Identifier: types.PkgIdentifier{ - PURL: &packageurl.PackageURL{ - Type: packageurl.TypeBitnami, - Name: "elasticsearch", - Version: "8.9.1", - Qualifiers: packageurl.Qualifiers{ - { - Key: "arch", - Value: "arm64", - }, - }, - }, - }, - }, - }, - }, }, }, wantErr: require.NoError, @@ -125,7 +126,8 @@ func Test_sbomAnalyzer_Analyze(t *testing.T) { want: &analyzer.AnalysisResult{ Applications: []types.Application{ { - Type: types.Jar, + Type: types.Jar, + FilePath: "opt/bitnami/elasticsearch/.spdx-elasticsearch.cdx", Packages: types.Packages{ { FilePath: "opt/bitnami/elasticsearch/modules/apm/elastic-apm-agent-1.36.0.jar",