diff --git a/syft/pkg/cataloger/binary/classifier_cataloger_test.go b/syft/pkg/cataloger/binary/classifier_cataloger_test.go index ab5af2703..987e2be80 100644 --- a/syft/pkg/cataloger/binary/classifier_cataloger_test.go +++ b/syft/pkg/cataloger/binary/classifier_cataloger_test.go @@ -1268,28 +1268,6 @@ func Test_Cataloger_PositiveCases(t *testing.T) { Metadata: metadata("consul-binary"), }, }, - { - logicalFixture: "consul/1.12.9/linux-amd64", - expected: pkg.Package{ - Name: "consul", - Version: "1.12.9", - Type: "binary", - PURL: "pkg:golang/github.com/hashicorp/consul@1.12.9", - Locations: locations("consul"), - Metadata: metadata("consul-binary"), - }, - }, - { - logicalFixture: "consul/1.7.14/linux-amd64", - expected: pkg.Package{ - Name: "consul", - Version: "1.7.14", - Type: "binary", - PURL: "pkg:golang/github.com/hashicorp/consul@1.7.14", - Locations: locations("consul"), - Metadata: metadata("consul-binary"), - }, - }, { logicalFixture: "vault/1.21.0-rc1/linux-amd64", expected: pkg.Package{ diff --git a/syft/pkg/cataloger/binary/classifiers.go b/syft/pkg/cataloger/binary/classifiers.go index 52a9be871..207d39592 100644 --- a/syft/pkg/cataloger/binary/classifiers.go +++ b/syft/pkg/cataloger/binary/classifiers.go @@ -657,19 +657,9 @@ func DefaultClassifiers() []binutils.Classifier { { Class: "consul-binary", FileGlob: "**/consul", - EvidenceMatcher: binutils.MatchAny( - m.FileContentsVersionMatcher( - // NOTE: This is brittle and may not work for past or future versions - `CONSUL_VERSION: (?P\d+\.\d+\.\d+)`, - ), - m.FileContentsVersionMatcher( - // GitDescribe=1.12.9" - `GitDescribe=(?P\d+\.\d+\.\d+)\"`, - ), - m.FileContentsVersionMatcher( - // [NUL][NUL][NUL]v1.7.14[NUL][NUL][NUL] - `\x00+v(?P\d+\.\d+\.\d+)\x00+`, - ), + EvidenceMatcher: m.FileContentsVersionMatcher( + // NOTE: This is brittle and may not work for past or future versions + `CONSUL_VERSION: (?P\d+\.\d+\.\d+)`, ), Package: "consul", PURL: mustPURL("pkg:golang/github.com/hashicorp/consul@version"), diff --git a/syft/pkg/cataloger/binary/testdata/classifiers/snippets/consul/1.12.9/linux-amd64/consul b/syft/pkg/cataloger/binary/testdata/classifiers/snippets/consul/1.12.9/linux-amd64/consul deleted file mode 100644 index f832c746e..000000000 --- a/syft/pkg/cataloger/binary/testdata/classifiers/snippets/consul/1.12.9/linux-amd64/consul +++ /dev/null @@ -1,14 +0,0 @@ -name: consul -offset: 52534344 -length: 220 -snippetSha256: ca576f5ee181015359ecf2a2d3b7431593816d510cb1fd03014998128ebfd54c -fileSha256: fc2840fe55664ccc8c197debca3a2f09e907ef0a55cbf3d239d8ea63f66fc96d - -### byte snippet to follow ### - -build -compiler=gc -build -ldflags="-X github.com/hashicorp/consul/version.GitCommit=96505027 -X github.com/hashicorp/consul/version.GitDescribe=1.12.9" -build CGO_ENABLED=0 -build GOARCH=amd64 -build GOOS=linux -build GOAMD \ No newline at end of file diff --git a/syft/pkg/cataloger/binary/testdata/classifiers/snippets/consul/1.7.14/linux-amd64/consul b/syft/pkg/cataloger/binary/testdata/classifiers/snippets/consul/1.7.14/linux-amd64/consul deleted file mode 100644 index 885afc7d5..000000000 Binary files a/syft/pkg/cataloger/binary/testdata/classifiers/snippets/consul/1.7.14/linux-amd64/consul and /dev/null differ diff --git a/syft/pkg/cataloger/binary/testdata/config.yaml b/syft/pkg/cataloger/binary/testdata/config.yaml index 5f8fa88aa..bbc2df0dd 100644 --- a/syft/pkg/cataloger/binary/testdata/config.yaml +++ b/syft/pkg/cataloger/binary/testdata/config.yaml @@ -931,20 +931,6 @@ from-images: paths: - /bin/consul - - version: 1.12.9 - images: - - ref: hashicorp/consul:1.12.9@sha256:609cce8f5e22953c89e284ca3a763e1dfff0bae6a6169e4e0a0ce23dce82faa2 - platform: linux/amd64 - paths: - - /bin/consul - - - version: 1.7.14 - images: - - ref: hashicorp/consul:1.7.14@sha256:882bbcef624bd9b7d37228d891a5d9b2698be2a55b5a658fd1c4ffb643d1f30d - platform: linux/amd64 - paths: - - /bin/consul - - version: 1.21.0-rc1 images: - ref: hashicorp/vault:1.21.0-rc1@sha256:67523b1e97acc26b050bb74abd251effe728bc3c1d7e80af19d251a511aa68ad diff --git a/syft/pkg/cataloger/swift/package.go b/syft/pkg/cataloger/swift/package.go index c4370f5dc..78050d0ab 100644 --- a/syft/pkg/cataloger/swift/package.go +++ b/syft/pkg/cataloger/swift/package.go @@ -62,10 +62,41 @@ func swiftPackageManagerPackageURL(name, version, sourceURL string) string { return packageurl.NewPackageURL( packageurl.TypeSwift, - strings.Replace(sourceURL, "https://", "", 1), + swiftNamespaceFromSourceURL(sourceURL, name), name, version, qualifiers, "", ).ToString() } + +// swiftNamespaceFromSourceURL derives the purl namespace (e.g. +// "github.com/apple") from a Swift Package.resolved source URL like +// "https://github.com/apple/swift-nio-ssl.git". +// +// Two bits of cleanup are needed compared with the previous +// strings.Replace(sourceURL, "https://", "", 1) behaviour: +// +// 1. Strip the ".git" suffix. Swift Package.resolved always carries the +// repository URL with a trailing ".git", but the purl spec uses the +// plain web path. +// 2. Drop the trailing / segment. The previous code left the repo +// name in the namespace and then appended the package name again, so +// the emitted purl looked like +// pkg:swift/github.com/apple/swift-nio-ssl.git/swift-nio-ssl@2.0.0 +// which Grype cannot match against NVD. The expected form is +// pkg:swift/github.com/apple/swift-nio-ssl@2.0.0 +// which is also what cdxgen emits. See anchore/syft#3961. +func swiftNamespaceFromSourceURL(sourceURL, name string) string { + ns := sourceURL + for _, prefix := range []string{"https://", "http://", "git+ssh://", "ssh://"} { + ns = strings.TrimPrefix(ns, prefix) + } + ns = strings.TrimSuffix(ns, ".git") + if name != "" { + if trimmed := strings.TrimSuffix(ns, "/"+name); trimmed != ns { + ns = trimmed + } + } + return ns +} diff --git a/syft/pkg/cataloger/swift/parse_package_resolved_test.go b/syft/pkg/cataloger/swift/parse_package_resolved_test.go index cd2565924..494a164c1 100644 --- a/syft/pkg/cataloger/swift/parse_package_resolved_test.go +++ b/syft/pkg/cataloger/swift/parse_package_resolved_test.go @@ -20,7 +20,7 @@ func TestParsePackageResolved(t *testing.T) { { Name: "swift-algorithms", Version: "1.0.0", - PURL: "pkg:swift/github.com/apple/swift-algorithms.git/swift-algorithms@1.0.0", + PURL: "pkg:swift/github.com/apple/swift-algorithms@1.0.0", Locations: locations, Language: pkg.Swift, Type: pkg.SwiftPkg, @@ -31,7 +31,7 @@ func TestParsePackageResolved(t *testing.T) { { Name: "swift-async-algorithms", Version: "0.1.0", - PURL: "pkg:swift/github.com/apple/swift-async-algorithms.git/swift-async-algorithms@0.1.0", + PURL: "pkg:swift/github.com/apple/swift-async-algorithms@0.1.0", Locations: locations, Language: pkg.Swift, Type: pkg.SwiftPkg, @@ -42,7 +42,7 @@ func TestParsePackageResolved(t *testing.T) { { Name: "swift-atomics", Version: "1.1.0", - PURL: "pkg:swift/github.com/apple/swift-atomics.git/swift-atomics@1.1.0", + PURL: "pkg:swift/github.com/apple/swift-atomics@1.1.0", Locations: locations, Language: pkg.Swift, Type: pkg.SwiftPkg, @@ -53,7 +53,7 @@ func TestParsePackageResolved(t *testing.T) { { Name: "swift-collections", Version: "1.0.4", - PURL: "pkg:swift/github.com/apple/swift-collections.git/swift-collections@1.0.4", + PURL: "pkg:swift/github.com/apple/swift-collections@1.0.4", Locations: locations, Language: pkg.Swift, Type: pkg.SwiftPkg, @@ -64,7 +64,7 @@ func TestParsePackageResolved(t *testing.T) { { Name: "swift-numerics", Version: "1.0.2", - PURL: "pkg:swift/github.com/apple/swift-numerics/swift-numerics@1.0.2", + PURL: "pkg:swift/github.com/apple/swift-numerics@1.0.2", Locations: locations, Language: pkg.Swift, Type: pkg.SwiftPkg, @@ -87,7 +87,7 @@ func TestParsePackageResolvedV3(t *testing.T) { { Name: "swift-mmio", Version: "", - PURL: "pkg:swift/github.com/apple/swift-mmio/swift-mmio", + PURL: "pkg:swift/github.com/apple/swift-mmio", Locations: locations, Language: pkg.Swift, Type: pkg.SwiftPkg, @@ -98,7 +98,7 @@ func TestParsePackageResolvedV3(t *testing.T) { { Name: "swift-syntax", Version: "509.1.1", - PURL: "pkg:swift/github.com/apple/swift-syntax.git/swift-syntax@509.1.1", + PURL: "pkg:swift/github.com/apple/swift-syntax@509.1.1", Locations: locations, Language: pkg.Swift, Type: pkg.SwiftPkg,