mirror of
https://github.com/anchore/syft.git
synced 2026-08-19 16:48:27 +02:00
fix(rust): omit Cargo PURLs for local packages (#5105)
Signed-off-by: Enes Deniz <142517728+3nesdeniz@users.noreply.github.com>
This commit is contained in:
parent
2dcf5163b8
commit
86baeeb481
@ -14,7 +14,7 @@ func newPackageFromCargoMetadata(m pkg.RustCargoLockEntry, locations ...file.Loc
|
||||
Name: m.Name,
|
||||
Version: m.Version,
|
||||
Locations: file.NewLocationSet(locations...),
|
||||
PURL: packageURL(m.Name, m.Version),
|
||||
PURL: cargoLockPackageURL(m),
|
||||
Language: pkg.Rust,
|
||||
Type: pkg.RustPkg,
|
||||
Metadata: m,
|
||||
@ -25,6 +25,18 @@ func newPackageFromCargoMetadata(m pkg.RustCargoLockEntry, locations ...file.Loc
|
||||
return p
|
||||
}
|
||||
|
||||
func cargoLockPackageURL(m pkg.RustCargoLockEntry) string {
|
||||
// Cargo omits source for packages resolved from the local workspace or a
|
||||
// path dependency. A cargo PURL without a repository qualifier identifies
|
||||
// a package on crates.io, so emitting one for a local package can cause
|
||||
// downstream scanners to match unrelated registry vulnerabilities.
|
||||
if m.Source == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
return packageURL(m.Name, m.Version)
|
||||
}
|
||||
|
||||
func newPackageFromAudit(dep *rustaudit.Package, locations ...file.Location) pkg.Package {
|
||||
p := pkg.Package{
|
||||
Name: dep.Name,
|
||||
|
||||
@ -4,6 +4,8 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/anchore/syft/syft/pkg"
|
||||
)
|
||||
|
||||
func Test_packageURL(t *testing.T) {
|
||||
@ -31,3 +33,34 @@ func Test_packageURL(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewPackageFromCargoMetadataPURL(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
source string
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "crates.io package",
|
||||
source: "registry+https://github.com/rust-lang/crates.io-index",
|
||||
want: "pkg:cargo/telemetry@0.1.0",
|
||||
},
|
||||
{
|
||||
name: "local path package",
|
||||
source: "",
|
||||
want: "",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := newPackageFromCargoMetadata(pkg.RustCargoLockEntry{
|
||||
Name: "telemetry",
|
||||
Version: "0.1.0",
|
||||
Source: tt.source,
|
||||
})
|
||||
|
||||
assert.Equal(t, tt.want, got.PURL)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@ -351,7 +351,7 @@ func TestCargoLockWithGitDependencies(t *testing.T) {
|
||||
helloWorld := pkg.Package{
|
||||
Name: "hello_world",
|
||||
Version: "0.1.0",
|
||||
PURL: "pkg:cargo/hello_world@0.1.0",
|
||||
PURL: "",
|
||||
Locations: locations,
|
||||
Language: pkg.Rust,
|
||||
Type: pkg.RustPkg,
|
||||
@ -673,6 +673,77 @@ func TestCargoLockWithGitDependencies(t *testing.T) {
|
||||
pkgtest.TestFileParser(t, fixture, parseCargoLock, expectedPkgs, expectedRelationships)
|
||||
}
|
||||
|
||||
func TestCargoLockWithPathDependencies(t *testing.T) {
|
||||
fixture := "testdata/path-deps/Cargo.lock"
|
||||
locations := file.NewLocationSet(file.NewLocation(fixture))
|
||||
|
||||
app := pkg.Package{
|
||||
Name: "app",
|
||||
Version: "1.0.0",
|
||||
Locations: locations,
|
||||
Language: pkg.Rust,
|
||||
Type: pkg.RustPkg,
|
||||
Licenses: pkg.NewLicenseSet(),
|
||||
Metadata: pkg.RustCargoLockEntry{
|
||||
Name: "app",
|
||||
Version: "1.0.0",
|
||||
Dependencies: []string{
|
||||
"memchr",
|
||||
"telemetry",
|
||||
},
|
||||
},
|
||||
}
|
||||
memchr := pkg.Package{
|
||||
Name: "memchr",
|
||||
Version: "2.7.4",
|
||||
PURL: "pkg:cargo/memchr@2.7.4",
|
||||
Locations: locations,
|
||||
Language: pkg.Rust,
|
||||
Type: pkg.RustPkg,
|
||||
Licenses: pkg.NewLicenseSet(),
|
||||
Metadata: pkg.RustCargoLockEntry{
|
||||
Name: "memchr",
|
||||
Version: "2.7.4",
|
||||
Source: "registry+https://github.com/rust-lang/crates.io-index",
|
||||
Checksum: "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3",
|
||||
Dependencies: []string{},
|
||||
},
|
||||
}
|
||||
telemetry := pkg.Package{
|
||||
Name: "telemetry",
|
||||
Version: "0.1.0",
|
||||
Locations: locations,
|
||||
Language: pkg.Rust,
|
||||
Type: pkg.RustPkg,
|
||||
Licenses: pkg.NewLicenseSet(),
|
||||
Metadata: pkg.RustCargoLockEntry{
|
||||
Name: "telemetry",
|
||||
Version: "0.1.0",
|
||||
Dependencies: []string{},
|
||||
},
|
||||
}
|
||||
|
||||
expectedPkgs := []pkg.Package{
|
||||
app,
|
||||
memchr,
|
||||
telemetry,
|
||||
}
|
||||
expectedRelationships := []artifact.Relationship{
|
||||
{
|
||||
From: memchr,
|
||||
To: app,
|
||||
Type: artifact.DependencyOfRelationship,
|
||||
},
|
||||
{
|
||||
From: telemetry,
|
||||
To: app,
|
||||
Type: artifact.DependencyOfRelationship,
|
||||
},
|
||||
}
|
||||
|
||||
pkgtest.TestFileParser(t, fixture, parseCargoLock, expectedPkgs, expectedRelationships)
|
||||
}
|
||||
|
||||
func TestCargoLockDependencySpecification(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
|
||||
21
syft/pkg/cataloger/rust/testdata/path-deps/Cargo.lock
generated
vendored
Normal file
21
syft/pkg/cataloger/rust/testdata/path-deps/Cargo.lock
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "app"
|
||||
version = "1.0.0"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"telemetry",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
|
||||
[[package]]
|
||||
name = "telemetry"
|
||||
version = "0.1.0"
|
||||
Loading…
x
Reference in New Issue
Block a user