mirror of
https://github.com/anchore/syft.git
synced 2025-11-17 16:33:21 +01:00
fix order of rust dependencies and support git sources in Cargo.lock dependencies (#3502)
* fix: un-reverse Cargo.lock dependencies Previously, dependencyOf was pointing the wrong way. Use dependency specification helpers to build the dependency graph. Signed-off-by: Will Murphy <willmurphyscode@users.noreply.github.com> * feat: parse Cargo.lock git dependency relationships Signed-off-by: Will Murphy <willmurphyscode@users.noreply.github.com> --------- Signed-off-by: Will Murphy <willmurphyscode@users.noreply.github.com>
This commit is contained in:
parent
d3c9ce532d
commit
4adb56d2fe
@ -3,14 +3,17 @@ package rust
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/pelletier/go-toml"
|
"github.com/pelletier/go-toml"
|
||||||
|
|
||||||
|
"github.com/anchore/syft/internal/log"
|
||||||
"github.com/anchore/syft/internal/unknown"
|
"github.com/anchore/syft/internal/unknown"
|
||||||
"github.com/anchore/syft/syft/artifact"
|
"github.com/anchore/syft/syft/artifact"
|
||||||
"github.com/anchore/syft/syft/file"
|
"github.com/anchore/syft/syft/file"
|
||||||
"github.com/anchore/syft/syft/pkg"
|
"github.com/anchore/syft/syft/pkg"
|
||||||
"github.com/anchore/syft/syft/pkg/cataloger/generic"
|
"github.com/anchore/syft/syft/pkg/cataloger/generic"
|
||||||
|
"github.com/anchore/syft/syft/pkg/cataloger/internal/dependency"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ generic.Parser = parseCargoLock
|
var _ generic.Parser = parseCargoLock
|
||||||
@ -33,7 +36,6 @@ func parseCargoLock(_ context.Context, _ file.Resolver, _ *generic.Environment,
|
|||||||
}
|
}
|
||||||
|
|
||||||
var pkgs []pkg.Package
|
var pkgs []pkg.Package
|
||||||
pkgIndex := make(map[string]int)
|
|
||||||
|
|
||||||
for _, p := range m.Packages {
|
for _, p := range m.Packages {
|
||||||
if p.Dependencies == nil {
|
if p.Dependencies == nil {
|
||||||
@ -47,36 +49,42 @@ func parseCargoLock(_ context.Context, _ file.Resolver, _ *generic.Environment,
|
|||||||
pkgs,
|
pkgs,
|
||||||
newPkg,
|
newPkg,
|
||||||
)
|
)
|
||||||
newIx := len(pkgs) - 1
|
|
||||||
// Cargo.lock dependencies are strings that are the name of a package, if that
|
|
||||||
// is unambiguous, or a string like "name version" if the name alone is not
|
|
||||||
// ambiguous. Set both keys in the map, since we don't know which key is
|
|
||||||
// going to be used until we're trying to resolve dependencies. If the
|
|
||||||
// first key is overwritten, that means the package name was an ambiguous dependency
|
|
||||||
// and "name version" will be used as the key anyway.
|
|
||||||
keys := []string{
|
|
||||||
newPkg.Name,
|
|
||||||
fmt.Sprintf("%s %s", newPkg.Name, newPkg.Version),
|
|
||||||
}
|
|
||||||
for _, k := range keys {
|
|
||||||
pkgIndex[k] = newIx
|
|
||||||
}
|
|
||||||
}
|
|
||||||
var relationships []artifact.Relationship
|
|
||||||
for _, p := range pkgs {
|
|
||||||
meta := p.Metadata.(pkg.RustCargoLockEntry)
|
|
||||||
for _, d := range meta.Dependencies {
|
|
||||||
i, ok := pkgIndex[d]
|
|
||||||
if !ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
relationships = append(relationships, artifact.Relationship{
|
|
||||||
From: p,
|
|
||||||
To: pkgs[i],
|
|
||||||
Type: artifact.DependencyOfRelationship,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return pkgs, relationships, unknown.IfEmptyf(pkgs, "unable to determine packages")
|
return pkgs, dependency.Resolve(dependencySpecification, pkgs), unknown.IfEmptyf(pkgs, "unable to determine packages")
|
||||||
|
}
|
||||||
|
|
||||||
|
func dependencySpecification(p pkg.Package) dependency.Specification {
|
||||||
|
rustMeta, ok := p.Metadata.(pkg.RustCargoLockEntry)
|
||||||
|
if !ok {
|
||||||
|
log.Tracef("cataloger failed to extract rust Cargo.lock metadata for package %+v", p.Name)
|
||||||
|
return dependency.Specification{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cargo.lock dependencies are strings that are the name of a package, if that
|
||||||
|
// is unambiguous, or a string like "name version" if the name alone is not
|
||||||
|
// ambiguous, or strings like "name version (source)" if "name version" is ambiguous.
|
||||||
|
// Provide all the strings, since we don't know which string will be used.
|
||||||
|
// In other words, each package "provides" 3 entries, one for each name format,
|
||||||
|
// and each package "requires" whatever it actually requires based on the Cargo.lock.
|
||||||
|
provides := []string{
|
||||||
|
p.Name,
|
||||||
|
fmt.Sprintf("%s %s", p.Name, p.Version),
|
||||||
|
}
|
||||||
|
|
||||||
|
if rustMeta.Source != "" {
|
||||||
|
src := rustMeta.Source
|
||||||
|
if strings.HasPrefix(src, "git") && strings.Contains(src, "#") {
|
||||||
|
src = strings.Split(src, "#")[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
provides = append(provides, fmt.Sprintf("%s %s (%s)", p.Name, p.Version, src))
|
||||||
|
}
|
||||||
|
|
||||||
|
return dependency.Specification{
|
||||||
|
ProvidesRequires: dependency.ProvidesRequires{
|
||||||
|
Provides: provides,
|
||||||
|
Requires: rustMeta.Dependencies,
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,8 @@ package rust
|
|||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
"github.com/anchore/syft/syft/artifact"
|
"github.com/anchore/syft/syft/artifact"
|
||||||
"github.com/anchore/syft/syft/file"
|
"github.com/anchore/syft/syft/file"
|
||||||
"github.com/anchore/syft/syft/pkg"
|
"github.com/anchore/syft/syft/pkg"
|
||||||
@ -279,43 +281,43 @@ func TestParseCargoLock(t *testing.T) {
|
|||||||
|
|
||||||
expectedRelationships := []artifact.Relationship{
|
expectedRelationships := []artifact.Relationship{
|
||||||
{
|
{
|
||||||
From: ansiTerm,
|
To: ansiTerm,
|
||||||
|
From: winapi,
|
||||||
|
Type: artifact.DependencyOfRelationship,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
To: errno,
|
||||||
|
From: windowsSys52,
|
||||||
|
Type: artifact.DependencyOfRelationship,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
To: nom,
|
||||||
|
From: memchr,
|
||||||
|
Type: artifact.DependencyOfRelationship,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
To: nom,
|
||||||
|
From: versionCheck,
|
||||||
|
Type: artifact.DependencyOfRelationship,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
To: schannel,
|
||||||
|
From: windowsSys59,
|
||||||
|
Type: artifact.DependencyOfRelationship,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
To: unicodeBidi,
|
||||||
|
From: matches,
|
||||||
|
Type: artifact.DependencyOfRelationship,
|
||||||
|
},
|
||||||
|
{
|
||||||
To: winapi,
|
To: winapi,
|
||||||
|
From: winAPIi686PCWindowsGNU,
|
||||||
Type: artifact.DependencyOfRelationship,
|
Type: artifact.DependencyOfRelationship,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
From: errno,
|
To: winapi,
|
||||||
To: windowsSys52,
|
From: winAPIx8664PCWindowsGNU,
|
||||||
Type: artifact.DependencyOfRelationship,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
From: nom,
|
|
||||||
To: memchr,
|
|
||||||
Type: artifact.DependencyOfRelationship,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
From: nom,
|
|
||||||
To: versionCheck,
|
|
||||||
Type: artifact.DependencyOfRelationship,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
From: schannel,
|
|
||||||
To: windowsSys59,
|
|
||||||
Type: artifact.DependencyOfRelationship,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
From: unicodeBidi,
|
|
||||||
To: matches,
|
|
||||||
Type: artifact.DependencyOfRelationship,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
From: winapi,
|
|
||||||
To: winAPIi686PCWindowsGNU,
|
|
||||||
Type: artifact.DependencyOfRelationship,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
From: winapi,
|
|
||||||
To: winAPIx8664PCWindowsGNU,
|
|
||||||
Type: artifact.DependencyOfRelationship,
|
Type: artifact.DependencyOfRelationship,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -323,6 +325,513 @@ func TestParseCargoLock(t *testing.T) {
|
|||||||
pkgtest.TestFileParser(t, fixture, parseCargoLock, expectedPkgs, expectedRelationships)
|
pkgtest.TestFileParser(t, fixture, parseCargoLock, expectedPkgs, expectedRelationships)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCargoLockWithGitDependencies(t *testing.T) {
|
||||||
|
fixture := "test-fixtures/Cargo.lock-with-git-deps"
|
||||||
|
locations := file.NewLocationSet(file.NewLocation(fixture))
|
||||||
|
|
||||||
|
ahoCorasick := pkg.Package{
|
||||||
|
Name: "aho-corasick",
|
||||||
|
Version: "1.1.3",
|
||||||
|
PURL: "pkg:cargo/aho-corasick@1.1.3",
|
||||||
|
Locations: locations,
|
||||||
|
Language: pkg.Rust,
|
||||||
|
Type: pkg.RustPkg,
|
||||||
|
Licenses: pkg.NewLicenseSet(),
|
||||||
|
Metadata: pkg.RustCargoLockEntry{
|
||||||
|
Name: "aho-corasick",
|
||||||
|
Version: "1.1.3",
|
||||||
|
Source: "registry+https://github.com/rust-lang/crates.io-index",
|
||||||
|
Checksum: "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916",
|
||||||
|
Dependencies: []string{
|
||||||
|
"memchr",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
helloWorld := pkg.Package{
|
||||||
|
Name: "hello_world",
|
||||||
|
Version: "0.1.0",
|
||||||
|
PURL: "pkg:cargo/hello_world@0.1.0",
|
||||||
|
Locations: locations,
|
||||||
|
Language: pkg.Rust,
|
||||||
|
Type: pkg.RustPkg,
|
||||||
|
Licenses: pkg.NewLicenseSet(),
|
||||||
|
Metadata: pkg.RustCargoLockEntry{
|
||||||
|
Name: "hello_world",
|
||||||
|
Version: "0.1.0",
|
||||||
|
Dependencies: []string{
|
||||||
|
"nom-regex",
|
||||||
|
"regex 1.11.1 (git+https://github.com/rust-lang/regex.git)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
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{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
minimalLexical := pkg.Package{
|
||||||
|
Name: "minimal-lexical",
|
||||||
|
Version: "0.2.1",
|
||||||
|
PURL: "pkg:cargo/minimal-lexical@0.2.1",
|
||||||
|
Locations: locations,
|
||||||
|
Language: pkg.Rust,
|
||||||
|
Type: pkg.RustPkg,
|
||||||
|
Licenses: pkg.NewLicenseSet(),
|
||||||
|
Metadata: pkg.RustCargoLockEntry{
|
||||||
|
Name: "minimal-lexical",
|
||||||
|
Version: "0.2.1",
|
||||||
|
Source: "registry+https://github.com/rust-lang/crates.io-index",
|
||||||
|
Checksum: "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a",
|
||||||
|
Dependencies: []string{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
nom := pkg.Package{
|
||||||
|
Name: "nom",
|
||||||
|
Version: "7.1.3",
|
||||||
|
PURL: "pkg:cargo/nom@7.1.3",
|
||||||
|
Locations: locations,
|
||||||
|
Language: pkg.Rust,
|
||||||
|
Type: pkg.RustPkg,
|
||||||
|
Licenses: pkg.NewLicenseSet(),
|
||||||
|
Metadata: pkg.RustCargoLockEntry{
|
||||||
|
Name: "nom",
|
||||||
|
Version: "7.1.3",
|
||||||
|
Source: "registry+https://github.com/rust-lang/crates.io-index",
|
||||||
|
Checksum: "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a",
|
||||||
|
Dependencies: []string{
|
||||||
|
"memchr",
|
||||||
|
"minimal-lexical",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
nomRegex := pkg.Package{
|
||||||
|
Name: "nom-regex",
|
||||||
|
Version: "0.2.0",
|
||||||
|
PURL: "pkg:cargo/nom-regex@0.2.0",
|
||||||
|
Locations: locations,
|
||||||
|
Language: pkg.Rust,
|
||||||
|
Type: pkg.RustPkg,
|
||||||
|
Licenses: pkg.NewLicenseSet(),
|
||||||
|
Metadata: pkg.RustCargoLockEntry{
|
||||||
|
Name: "nom-regex",
|
||||||
|
Version: "0.2.0",
|
||||||
|
Source: "registry+https://github.com/rust-lang/crates.io-index",
|
||||||
|
Checksum: "72e5c7731c4c1370b61604ed52a2475e861aac9e08dec9f23903d4ddfdc91c18",
|
||||||
|
Dependencies: []string{
|
||||||
|
"nom",
|
||||||
|
"regex 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
regexCrates := pkg.Package{
|
||||||
|
Name: "regex",
|
||||||
|
Version: "1.11.1",
|
||||||
|
PURL: "pkg:cargo/regex@1.11.1",
|
||||||
|
Locations: locations,
|
||||||
|
Language: pkg.Rust,
|
||||||
|
Type: pkg.RustPkg,
|
||||||
|
Licenses: pkg.NewLicenseSet(),
|
||||||
|
Metadata: pkg.RustCargoLockEntry{
|
||||||
|
Name: "regex",
|
||||||
|
Version: "1.11.1",
|
||||||
|
Source: "registry+https://github.com/rust-lang/crates.io-index",
|
||||||
|
Checksum: "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191",
|
||||||
|
Dependencies: []string{
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-automata 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"regex-syntax 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
regexGit := pkg.Package{
|
||||||
|
Name: "regex",
|
||||||
|
Version: "1.11.1",
|
||||||
|
PURL: "pkg:cargo/regex@1.11.1",
|
||||||
|
Locations: locations,
|
||||||
|
Language: pkg.Rust,
|
||||||
|
Type: pkg.RustPkg,
|
||||||
|
Licenses: pkg.NewLicenseSet(),
|
||||||
|
Metadata: pkg.RustCargoLockEntry{
|
||||||
|
Name: "regex",
|
||||||
|
Version: "1.11.1",
|
||||||
|
Source: "git+https://github.com/rust-lang/regex.git#1a069b9232c607b34c4937122361aa075ef573fa",
|
||||||
|
Dependencies: []string{
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-automata 0.4.9 (git+https://github.com/rust-lang/regex.git)",
|
||||||
|
"regex-syntax 0.8.5 (git+https://github.com/rust-lang/regex.git)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
regexAutomataCrates := pkg.Package{
|
||||||
|
Name: "regex-automata",
|
||||||
|
Version: "0.4.9",
|
||||||
|
PURL: "pkg:cargo/regex-automata@0.4.9",
|
||||||
|
Locations: locations,
|
||||||
|
Language: pkg.Rust,
|
||||||
|
Type: pkg.RustPkg,
|
||||||
|
Licenses: pkg.NewLicenseSet(),
|
||||||
|
Metadata: pkg.RustCargoLockEntry{
|
||||||
|
Name: "regex-automata",
|
||||||
|
Version: "0.4.9",
|
||||||
|
Source: "registry+https://github.com/rust-lang/crates.io-index",
|
||||||
|
Checksum: "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908",
|
||||||
|
Dependencies: []string{
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-syntax 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
regexAutomataGit := pkg.Package{
|
||||||
|
Name: "regex-automata",
|
||||||
|
Version: "0.4.9",
|
||||||
|
PURL: "pkg:cargo/regex-automata@0.4.9",
|
||||||
|
Locations: locations,
|
||||||
|
Language: pkg.Rust,
|
||||||
|
Type: pkg.RustPkg,
|
||||||
|
Licenses: pkg.NewLicenseSet(),
|
||||||
|
Metadata: pkg.RustCargoLockEntry{
|
||||||
|
Name: "regex-automata",
|
||||||
|
Version: "0.4.9",
|
||||||
|
Source: "git+https://github.com/rust-lang/regex.git#1a069b9232c607b34c4937122361aa075ef573fa",
|
||||||
|
Dependencies: []string{
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-syntax 0.8.5 (git+https://github.com/rust-lang/regex.git)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
regexSyntaxCrates := pkg.Package{
|
||||||
|
Name: "regex-syntax",
|
||||||
|
Version: "0.8.5",
|
||||||
|
PURL: "pkg:cargo/regex-syntax@0.8.5",
|
||||||
|
Locations: locations,
|
||||||
|
Language: pkg.Rust,
|
||||||
|
Type: pkg.RustPkg,
|
||||||
|
Licenses: pkg.NewLicenseSet(),
|
||||||
|
Metadata: pkg.RustCargoLockEntry{
|
||||||
|
Name: "regex-syntax",
|
||||||
|
Version: "0.8.5",
|
||||||
|
Source: "registry+https://github.com/rust-lang/crates.io-index",
|
||||||
|
Checksum: "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c",
|
||||||
|
Dependencies: []string{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
regexSyntaxGit := pkg.Package{
|
||||||
|
Name: "regex-syntax",
|
||||||
|
Version: "0.8.5",
|
||||||
|
PURL: "pkg:cargo/regex-syntax@0.8.5",
|
||||||
|
Locations: locations,
|
||||||
|
Language: pkg.Rust,
|
||||||
|
Type: pkg.RustPkg,
|
||||||
|
Licenses: pkg.NewLicenseSet(),
|
||||||
|
Metadata: pkg.RustCargoLockEntry{
|
||||||
|
Name: "regex-syntax",
|
||||||
|
Version: "0.8.5",
|
||||||
|
Source: "git+https://github.com/rust-lang/regex.git#1a069b9232c607b34c4937122361aa075ef573fa",
|
||||||
|
Dependencies: []string{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedPkgs := []pkg.Package{
|
||||||
|
ahoCorasick, helloWorld, memchr, minimalLexical, nom, nomRegex, regexCrates, regexGit,
|
||||||
|
regexAutomataCrates, regexAutomataGit, regexSyntaxCrates, regexSyntaxGit,
|
||||||
|
}
|
||||||
|
expectedRelationships := []artifact.Relationship{
|
||||||
|
{
|
||||||
|
From: memchr,
|
||||||
|
To: ahoCorasick,
|
||||||
|
Type: artifact.DependencyOfRelationship,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
From: nomRegex,
|
||||||
|
To: helloWorld,
|
||||||
|
Type: artifact.DependencyOfRelationship,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
From: regexGit,
|
||||||
|
To: helloWorld,
|
||||||
|
Type: artifact.DependencyOfRelationship,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
From: memchr,
|
||||||
|
To: nom,
|
||||||
|
Type: artifact.DependencyOfRelationship,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
From: minimalLexical,
|
||||||
|
To: nom,
|
||||||
|
Type: artifact.DependencyOfRelationship,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
From: nom,
|
||||||
|
To: nomRegex,
|
||||||
|
Type: artifact.DependencyOfRelationship,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
From: regexCrates,
|
||||||
|
To: nomRegex,
|
||||||
|
Type: artifact.DependencyOfRelationship,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
From: ahoCorasick,
|
||||||
|
To: regexCrates,
|
||||||
|
Type: artifact.DependencyOfRelationship,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
From: memchr,
|
||||||
|
To: regexCrates,
|
||||||
|
Type: artifact.DependencyOfRelationship,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
From: regexAutomataCrates,
|
||||||
|
To: regexCrates,
|
||||||
|
Type: artifact.DependencyOfRelationship,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
From: regexSyntaxCrates,
|
||||||
|
To: regexCrates,
|
||||||
|
Type: artifact.DependencyOfRelationship,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
From: regexSyntaxCrates,
|
||||||
|
To: regexAutomataCrates,
|
||||||
|
Type: artifact.DependencyOfRelationship,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
From: ahoCorasick,
|
||||||
|
To: regexGit,
|
||||||
|
Type: artifact.DependencyOfRelationship,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
From: memchr,
|
||||||
|
To: regexGit,
|
||||||
|
Type: artifact.DependencyOfRelationship,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
From: regexAutomataGit,
|
||||||
|
To: regexGit,
|
||||||
|
Type: artifact.DependencyOfRelationship,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
From: regexSyntaxGit,
|
||||||
|
To: regexAutomataGit,
|
||||||
|
Type: artifact.DependencyOfRelationship,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
From: regexSyntaxGit,
|
||||||
|
To: regexGit,
|
||||||
|
Type: artifact.DependencyOfRelationship,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
From: ahoCorasick,
|
||||||
|
To: regexAutomataCrates,
|
||||||
|
Type: artifact.DependencyOfRelationship,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
From: memchr,
|
||||||
|
To: regexAutomataCrates,
|
||||||
|
Type: artifact.DependencyOfRelationship,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
From: ahoCorasick,
|
||||||
|
To: regexAutomataGit,
|
||||||
|
Type: artifact.DependencyOfRelationship,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
From: memchr,
|
||||||
|
To: regexAutomataGit,
|
||||||
|
Type: artifact.DependencyOfRelationship,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
// what I know so far - it's not sorting, it's not
|
||||||
|
|
||||||
|
pkgtest.TestFileParser(t, fixture, parseCargoLock, expectedPkgs, expectedRelationships)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCargoLockDependencySpecification(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
p pkg.Package
|
||||||
|
provides []string
|
||||||
|
requires []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "requires git source",
|
||||||
|
p: pkg.Package{
|
||||||
|
Name: "hello_world",
|
||||||
|
Version: "0.1.0",
|
||||||
|
PURL: "pkg:cargo/hello_world@0.1.0",
|
||||||
|
Locations: file.NewLocationSet(),
|
||||||
|
Language: pkg.Rust,
|
||||||
|
Type: pkg.RustPkg,
|
||||||
|
Licenses: pkg.NewLicenseSet(),
|
||||||
|
Metadata: pkg.RustCargoLockEntry{
|
||||||
|
Name: "hello_world",
|
||||||
|
Version: "0.1.0",
|
||||||
|
Dependencies: []string{
|
||||||
|
"nom-regex",
|
||||||
|
"regex 1.11.1 (git+https://github.com/rust-lang/regex.git)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
provides: []string{
|
||||||
|
"hello_world",
|
||||||
|
"hello_world 0.1.0",
|
||||||
|
},
|
||||||
|
requires: []string{
|
||||||
|
"nom-regex",
|
||||||
|
"regex 1.11.1 (git+https://github.com/rust-lang/regex.git)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "provides git source",
|
||||||
|
p: pkg.Package{
|
||||||
|
Name: "regex-automata",
|
||||||
|
Version: "0.4.9",
|
||||||
|
PURL: "pkg:cargo/regex-automata@0.4.9",
|
||||||
|
Locations: file.NewLocationSet(),
|
||||||
|
Language: pkg.Rust,
|
||||||
|
Type: pkg.RustPkg,
|
||||||
|
Licenses: pkg.NewLicenseSet(),
|
||||||
|
Metadata: pkg.RustCargoLockEntry{
|
||||||
|
Name: "regex-automata",
|
||||||
|
Version: "0.4.9",
|
||||||
|
Source: "git+https://github.com/rust-lang/regex.git#1a069b9232c607b34c4937122361aa075ef573fa",
|
||||||
|
Dependencies: []string{
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-syntax 0.8.5 (git+https://github.com/rust-lang/regex.git)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
provides: []string{
|
||||||
|
"regex-automata",
|
||||||
|
"regex-automata 0.4.9",
|
||||||
|
"regex-automata 0.4.9 (git+https://github.com/rust-lang/regex.git)",
|
||||||
|
},
|
||||||
|
requires: []string{
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-syntax 0.8.5 (git+https://github.com/rust-lang/regex.git)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "regex-automata git",
|
||||||
|
p: pkg.Package{
|
||||||
|
Name: "regex-automata",
|
||||||
|
Version: "0.4.9",
|
||||||
|
PURL: "pkg:cargo/regex-automata@0.4.9",
|
||||||
|
Locations: file.NewLocationSet(),
|
||||||
|
Language: pkg.Rust,
|
||||||
|
Type: pkg.RustPkg,
|
||||||
|
Licenses: pkg.NewLicenseSet(),
|
||||||
|
Metadata: pkg.RustCargoLockEntry{
|
||||||
|
Name: "regex-automata",
|
||||||
|
Version: "0.4.9",
|
||||||
|
Source: "git+https://github.com/rust-lang/regex.git#1a069b9232c607b34c4937122361aa075ef573fa",
|
||||||
|
Dependencies: []string{
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-syntax 0.8.5 (git+https://github.com/rust-lang/regex.git)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
provides: []string{
|
||||||
|
"regex-automata",
|
||||||
|
"regex-automata 0.4.9",
|
||||||
|
"regex-automata 0.4.9 (git+https://github.com/rust-lang/regex.git)",
|
||||||
|
},
|
||||||
|
requires: []string{
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-syntax 0.8.5 (git+https://github.com/rust-lang/regex.git)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "regex-syntax git",
|
||||||
|
p: pkg.Package{
|
||||||
|
Name: "regex-syntax",
|
||||||
|
Version: "0.8.5",
|
||||||
|
PURL: "pkg:cargo/regex-syntax@0.8.5",
|
||||||
|
Locations: file.NewLocationSet(),
|
||||||
|
Language: pkg.Rust,
|
||||||
|
Type: pkg.RustPkg,
|
||||||
|
Licenses: pkg.NewLicenseSet(),
|
||||||
|
Metadata: pkg.RustCargoLockEntry{
|
||||||
|
Name: "regex-syntax",
|
||||||
|
Version: "0.8.5",
|
||||||
|
Source: "git+https://github.com/rust-lang/regex.git#1a069b9232c607b34c4937122361aa075ef573fa",
|
||||||
|
Dependencies: []string{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
provides: []string{
|
||||||
|
"regex-syntax",
|
||||||
|
"regex-syntax 0.8.5",
|
||||||
|
"regex-syntax 0.8.5 (git+https://github.com/rust-lang/regex.git)",
|
||||||
|
},
|
||||||
|
requires: []string{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "regex-syntax crates",
|
||||||
|
p: pkg.Package{
|
||||||
|
Name: "regex-syntax",
|
||||||
|
Version: "0.8.5",
|
||||||
|
PURL: "pkg:cargo/regex-syntax@0.8.5",
|
||||||
|
Locations: file.NewLocationSet(),
|
||||||
|
Language: pkg.Rust,
|
||||||
|
Type: pkg.RustPkg,
|
||||||
|
Licenses: pkg.NewLicenseSet(),
|
||||||
|
Metadata: pkg.RustCargoLockEntry{
|
||||||
|
Name: "regex-syntax",
|
||||||
|
Version: "0.8.5",
|
||||||
|
Source: "registry+https://github.com/rust-lang/crates.io-index",
|
||||||
|
Checksum: "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c",
|
||||||
|
Dependencies: []string{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
provides: []string{
|
||||||
|
"regex-syntax",
|
||||||
|
"regex-syntax 0.8.5",
|
||||||
|
"regex-syntax 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
},
|
||||||
|
requires: []string{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, test := range tests {
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
spec := dependencySpecification(test.p)
|
||||||
|
assert.Equal(t, test.provides, spec.Provides)
|
||||||
|
assert.Equal(t, test.requires, spec.Requires)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func Test_corruptCargoLock(t *testing.T) {
|
func Test_corruptCargoLock(t *testing.T) {
|
||||||
pkgtest.NewCatalogTester().
|
pkgtest.NewCatalogTester().
|
||||||
FromFile(t, "test-fixtures/glob-paths/src/Cargo.lock").
|
FromFile(t, "test-fixtures/glob-paths/src/Cargo.lock").
|
||||||
|
|||||||
107
syft/pkg/cataloger/rust/test-fixtures/Cargo.lock-with-git-deps
Normal file
107
syft/pkg/cataloger/rust/test-fixtures/Cargo.lock-with-git-deps
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aho-corasick"
|
||||||
|
version = "1.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hello_world"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"nom-regex",
|
||||||
|
"regex 1.11.1 (git+https://github.com/rust-lang/regex.git)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.7.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "minimal-lexical"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nom"
|
||||||
|
version = "7.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
"minimal-lexical",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nom-regex"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "72e5c7731c4c1370b61604ed52a2475e861aac9e08dec9f23903d4ddfdc91c18"
|
||||||
|
dependencies = [
|
||||||
|
"nom",
|
||||||
|
"regex 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex"
|
||||||
|
version = "1.11.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-automata 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
"regex-syntax 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex"
|
||||||
|
version = "1.11.1"
|
||||||
|
source = "git+https://github.com/rust-lang/regex.git#1a069b9232c607b34c4937122361aa075ef573fa"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-automata 0.4.9 (git+https://github.com/rust-lang/regex.git)",
|
||||||
|
"regex-syntax 0.8.5 (git+https://github.com/rust-lang/regex.git)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-automata"
|
||||||
|
version = "0.4.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-syntax 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-automata"
|
||||||
|
version = "0.4.9"
|
||||||
|
source = "git+https://github.com/rust-lang/regex.git#1a069b9232c607b34c4937122361aa075ef573fa"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-syntax 0.8.5 (git+https://github.com/rust-lang/regex.git)",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-syntax"
|
||||||
|
version = "0.8.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-syntax"
|
||||||
|
version = "0.8.5"
|
||||||
|
source = "git+https://github.com/rust-lang/regex.git#1a069b9232c607b34c4937122361aa075ef573fa"
|
||||||
Loading…
x
Reference in New Issue
Block a user