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"),
|
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",
|
logicalFixture: "vault/1.21.0-rc1/linux-amd64",
|
||||||
expected: pkg.Package{
|
expected: pkg.Package{
|
||||||
|
|||||||
@@ -657,19 +657,9 @@ func DefaultClassifiers() []binutils.Classifier {
|
|||||||
{
|
{
|
||||||
Class: "consul-binary",
|
Class: "consul-binary",
|
||||||
FileGlob: "**/consul",
|
FileGlob: "**/consul",
|
||||||
EvidenceMatcher: binutils.MatchAny(
|
EvidenceMatcher: m.FileContentsVersionMatcher(
|
||||||
m.FileContentsVersionMatcher(
|
// NOTE: This is brittle and may not work for past or future versions
|
||||||
// NOTE: This is brittle and may not work for past or future versions
|
`CONSUL_VERSION: (?P<version>\d+\.\d+\.\d+)`,
|
||||||
`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",
|
Package: "consul",
|
||||||
PURL: mustPURL("pkg:golang/github.com/hashicorp/consul@version"),
|
PURL: mustPURL("pkg:golang/github.com/hashicorp/consul@version"),
|
||||||
|
|||||||
-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:
|
paths:
|
||||||
- /bin/consul
|
- /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
|
- version: 1.21.0-rc1
|
||||||
images:
|
images:
|
||||||
- ref: hashicorp/vault:1.21.0-rc1@sha256:67523b1e97acc26b050bb74abd251effe728bc3c1d7e80af19d251a511aa68ad
|
- ref: hashicorp/vault:1.21.0-rc1@sha256:67523b1e97acc26b050bb74abd251effe728bc3c1d7e80af19d251a511aa68ad
|
||||||
|
|||||||
@@ -62,10 +62,41 @@ func swiftPackageManagerPackageURL(name, version, sourceURL string) string {
|
|||||||
|
|
||||||
return packageurl.NewPackageURL(
|
return packageurl.NewPackageURL(
|
||||||
packageurl.TypeSwift,
|
packageurl.TypeSwift,
|
||||||
strings.Replace(sourceURL, "https://", "", 1),
|
swiftNamespaceFromSourceURL(sourceURL, name),
|
||||||
name,
|
name,
|
||||||
version,
|
version,
|
||||||
qualifiers,
|
qualifiers,
|
||||||
"",
|
"",
|
||||||
).ToString()
|
).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",
|
Name: "swift-algorithms",
|
||||||
Version: "1.0.0",
|
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,
|
Locations: locations,
|
||||||
Language: pkg.Swift,
|
Language: pkg.Swift,
|
||||||
Type: pkg.SwiftPkg,
|
Type: pkg.SwiftPkg,
|
||||||
@@ -31,7 +31,7 @@ func TestParsePackageResolved(t *testing.T) {
|
|||||||
{
|
{
|
||||||
Name: "swift-async-algorithms",
|
Name: "swift-async-algorithms",
|
||||||
Version: "0.1.0",
|
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,
|
Locations: locations,
|
||||||
Language: pkg.Swift,
|
Language: pkg.Swift,
|
||||||
Type: pkg.SwiftPkg,
|
Type: pkg.SwiftPkg,
|
||||||
@@ -42,7 +42,7 @@ func TestParsePackageResolved(t *testing.T) {
|
|||||||
{
|
{
|
||||||
Name: "swift-atomics",
|
Name: "swift-atomics",
|
||||||
Version: "1.1.0",
|
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,
|
Locations: locations,
|
||||||
Language: pkg.Swift,
|
Language: pkg.Swift,
|
||||||
Type: pkg.SwiftPkg,
|
Type: pkg.SwiftPkg,
|
||||||
@@ -53,7 +53,7 @@ func TestParsePackageResolved(t *testing.T) {
|
|||||||
{
|
{
|
||||||
Name: "swift-collections",
|
Name: "swift-collections",
|
||||||
Version: "1.0.4",
|
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,
|
Locations: locations,
|
||||||
Language: pkg.Swift,
|
Language: pkg.Swift,
|
||||||
Type: pkg.SwiftPkg,
|
Type: pkg.SwiftPkg,
|
||||||
@@ -64,7 +64,7 @@ func TestParsePackageResolved(t *testing.T) {
|
|||||||
{
|
{
|
||||||
Name: "swift-numerics",
|
Name: "swift-numerics",
|
||||||
Version: "1.0.2",
|
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,
|
Locations: locations,
|
||||||
Language: pkg.Swift,
|
Language: pkg.Swift,
|
||||||
Type: pkg.SwiftPkg,
|
Type: pkg.SwiftPkg,
|
||||||
@@ -87,7 +87,7 @@ func TestParsePackageResolvedV3(t *testing.T) {
|
|||||||
{
|
{
|
||||||
Name: "swift-mmio",
|
Name: "swift-mmio",
|
||||||
Version: "",
|
Version: "",
|
||||||
PURL: "pkg:swift/github.com/apple/swift-mmio/swift-mmio",
|
PURL: "pkg:swift/github.com/apple/swift-mmio",
|
||||||
Locations: locations,
|
Locations: locations,
|
||||||
Language: pkg.Swift,
|
Language: pkg.Swift,
|
||||||
Type: pkg.SwiftPkg,
|
Type: pkg.SwiftPkg,
|
||||||
@@ -98,7 +98,7 @@ func TestParsePackageResolvedV3(t *testing.T) {
|
|||||||
{
|
{
|
||||||
Name: "swift-syntax",
|
Name: "swift-syntax",
|
||||||
Version: "509.1.1",
|
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,
|
Locations: locations,
|
||||||
Language: pkg.Swift,
|
Language: pkg.Swift,
|
||||||
Type: pkg.SwiftPkg,
|
Type: pkg.SwiftPkg,
|
||||||
|
|||||||
Reference in New Issue
Block a user