mirror of
https://github.com/anchore/syft.git
synced 2026-10-11 21:57:22 +02:00
swift: emit canonical purls without .git suffix or repeated name
Reported in anchore/syft#3961: the purl syft emits for Swift packages
parsed out of Package.resolved keeps the repository URLs .git suffix
and then re-appends the package name, producing
pkg:swift/github.com/apple/swift-nio-ssl.git/swift-nio-ssl@2.0.0
NVD / Grype cannot match that purl against the known
swift-nio-ssl@2.0.0 CVE (GHSA-frg3-gpcx-968f), so every Swift SBOM
produced by syft silently loses vulnerability coverage. cdxgen and
the wider purl ecosystem use the shorter form
pkg:swift/github.com/apple/swift-nio-ssl@2.0.0
which Grype does match.
Replace the ad-hoc strings.Replace with swiftNamespaceFromSourceURL,
which trims the common URL schemes, strips the ".git" suffix, and
drops a trailing /<name> segment so the namespace is only the
organisation path (e.g. github.com/apple). Existing test expectations
are updated to the new purl shape.
Fixes #3961
Signed-off-by: Sai Asish Y <say.apm35@gmail.com>
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
This commit is contained in:
@@ -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{
|
||||
|
||||
@@ -657,20 +657,10 @@ func DefaultClassifiers() []binutils.Classifier {
|
||||
{
|
||||
Class: "consul-binary",
|
||||
FileGlob: "**/consul",
|
||||
EvidenceMatcher: binutils.MatchAny(
|
||||
m.FileContentsVersionMatcher(
|
||||
EvidenceMatcher: m.FileContentsVersionMatcher(
|
||||
// NOTE: This is brittle and may not work for past or future versions
|
||||
`CONSUL_VERSION: (?P<version>\d+\.\d+\.\d+)`,
|
||||
),
|
||||
m.FileContentsVersionMatcher(
|
||||
// GitDescribe=1.12.9"
|
||||
`GitDescribe=(?P<version>\d+\.\d+\.\d+)\"`,
|
||||
),
|
||||
m.FileContentsVersionMatcher(
|
||||
// [NUL][NUL][NUL]v1.7.14[NUL][NUL][NUL]
|
||||
`\x00+v(?P<version>\d+\.\d+\.\d+)\x00+`,
|
||||
),
|
||||
),
|
||||
Package: "consul",
|
||||
PURL: mustPURL("pkg:golang/github.com/hashicorp/consul@version"),
|
||||
CPEs: singleCPE("cpe:2.3:a:hashicorp:consul:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||
|
||||
-14
@@ -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
|
||||
BIN
Binary file not shown.
-14
@@ -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
|
||||
|
||||
@@ -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 /<name> 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
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user