From f7ffcc534fd44e304527dfd34c6e0b372310456a Mon Sep 17 00:00:00 2001 From: Christopher Angelo Phillips <32073428+spiffcs@users.noreply.github.com> Date: Tue, 9 Jul 2024 14:24:21 -0400 Subject: [PATCH] fix: stabilize cpe sorting during collection sort (#3009) --- syft/cpe/by_source_then_specificity_test.go | 22 +++++++++++++++++++ .../internal/cpegenerate/generate.go | 3 ++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/syft/cpe/by_source_then_specificity_test.go b/syft/cpe/by_source_then_specificity_test.go index 9687447f9d8..7d62bba4ba7 100644 --- a/syft/cpe/by_source_then_specificity_test.go +++ b/syft/cpe/by_source_then_specificity_test.go @@ -64,6 +64,28 @@ func TestBySourceThenSpecificity(t *testing.T) { Must("cpe:2.3:a:some:package:*:*:*:*:*:*:*:*", "some-unknown-source"), }, }, + { + name: "lexical sorting on equal sources puts escaped characters later", + input: []CPE{ + Must("cpe:2.3:a:jenkins:pipeline\\\\:_supporting_apis:865.v43e78cc44e0d:*:*:*:*:jenkins:*:*", "nvd-cpe-dictionary"), + Must("cpe:2.3:a:jenkins:pipeline_supporting_apis:865.v43e78cc44e0d:*:*:*:*:jenkins:*:*", "nvd-cpe-dictionary"), + }, + want: []CPE{ + Must("cpe:2.3:a:jenkins:pipeline_supporting_apis:865.v43e78cc44e0d:*:*:*:*:jenkins:*:*", "nvd-cpe-dictionary"), + Must("cpe:2.3:a:jenkins:pipeline\\\\:_supporting_apis:865.v43e78cc44e0d:*:*:*:*:jenkins:*:*", "nvd-cpe-dictionary"), + }, + }, + { + name: "lexical sorting on equal sources puts more specific attributes earlier", + input: []CPE{ + Must("cpe:2.3:a:jenkins:mailer:472.vf7c289a_4b_420:*:*:*:*:*:*:*", "nvd-cpe-dictionary"), + Must("cpe:2.3:a:jenkins:mailer:472.vf7c289a_4b_420:*:*:*:*:jenkins:*:*", "nvd-cpe-dictionary"), + }, + want: []CPE{ + Must("cpe:2.3:a:jenkins:mailer:472.vf7c289a_4b_420:*:*:*:*:jenkins:*:*", "nvd-cpe-dictionary"), + Must("cpe:2.3:a:jenkins:mailer:472.vf7c289a_4b_420:*:*:*:*:*:*:*", "nvd-cpe-dictionary"), + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/syft/pkg/cataloger/internal/cpegenerate/generate.go b/syft/pkg/cataloger/internal/cpegenerate/generate.go index 174076460cf..ef8701657cc 100644 --- a/syft/pkg/cataloger/internal/cpegenerate/generate.go +++ b/syft/pkg/cataloger/internal/cpegenerate/generate.go @@ -127,6 +127,7 @@ func FromDictionaryFind(p pkg.Package) ([]cpe.CPE, bool) { return []cpe.CPE{}, false } + sort.Sort(cpe.BySourceThenSpecificity(parsedCPEs)) return parsedCPEs, true } @@ -163,12 +164,12 @@ func FromPackageAttributes(p pkg.Package) []cpe.CPE { // filter out any known combinations that don't accurately represent this package cpes = filter(cpes, p, cpeFilters...) - sort.Sort(cpe.BySpecificity(cpes)) var result []cpe.CPE for _, c := range cpes { result = append(result, cpe.CPE{Attributes: c, Source: cpe.GeneratedSource}) } + sort.Sort(cpe.BySourceThenSpecificity(result)) return result }