mirror of
https://github.com/anchore/syft.git
synced 2026-10-30 05:52:25 +01:00
fix: don't index nested packages under the outer archive path
`indexedPaths` added each location's `RealPath`, which for a nested file is the outermost archive. So
`PackagesByPath("/opt/x.jar")` returned every package found inside it at any depth, a root OS package
owning that file got ownership-overlap edges to all of them, and
`ExcludeBinaryPackagesWithFileOwnershipOverlap` then deleted nested binary, ELF and JVM packages.
Packages are now indexed by full path and access path only. An archive's own package still sits at
root coordinates and is found by its path; what's inside it stays linked to it by CONTAINS edges
rather than by ownership of the archive file.
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
This commit is contained in:
@@ -103,7 +103,9 @@ func TestOwnershipByFilesRelationship(t *testing.T) {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "top-level-owner-of-an-archive-owns-packages-within-it",
|
||||
// the archive's own package (when it has one) is found by its path; what is inside it is
|
||||
// linked to that package by CONTAINS, not owned by whoever owns the archive file
|
||||
name: "top-level-owner-of-an-archive-does-not-own-packages-within-it",
|
||||
setup: func(t testing.TB) ([]pkg.Package, []artifact.Relationship) {
|
||||
parent := pkg.Package{
|
||||
Locations: file.NewLocationSet(file.NewLocation("/var/lib/rpm/Packages")),
|
||||
@@ -123,14 +125,7 @@ func TestOwnershipByFilesRelationship(t *testing.T) {
|
||||
}
|
||||
child.SetID()
|
||||
|
||||
relationship := artifact.Relationship{
|
||||
From: parent,
|
||||
To: child,
|
||||
Type: artifact.OwnershipByFileOverlapRelationship,
|
||||
Data: ownershipByFilesMetadata{Files: []string{"/opt/bundle.tar"}},
|
||||
}
|
||||
|
||||
return []pkg.Package{parent, child}, []artifact.Relationship{relationship}
|
||||
return []pkg.Package{parent, child}, nil
|
||||
},
|
||||
},
|
||||
{
|
||||
|
||||
@@ -62,7 +62,7 @@ func (c *Collection) Package(id artifact.ID) *Package {
|
||||
}
|
||||
|
||||
// PackagesByPath returns all packages that were discovered from the given path: a file's full path or
|
||||
// access path, or the top path of an archive, which answers with every package found within it.
|
||||
// access path. A package found within an archive is not returned for the archive's own path.
|
||||
func (c *Collection) PackagesByPath(path string) []Package {
|
||||
c.lock.RLock()
|
||||
defer c.lock.RUnlock()
|
||||
@@ -164,12 +164,12 @@ func (c *Collection) addPathsToIndex(p Package) {
|
||||
}
|
||||
}
|
||||
|
||||
// indexedPaths are the paths a package is found by: each location's full path and access path, and
|
||||
// the top path of an archive it was found within.
|
||||
// indexedPaths are the paths a package is found by: each location's full path and access path. The real
|
||||
// path of a nested location is the outermost archive, so it is left out.
|
||||
func indexedPaths(p Package) []string {
|
||||
paths := strset.New()
|
||||
for _, l := range p.Locations.ToSlice() {
|
||||
paths.Add(l.RealPath, l.AccessPath, l.FullNestedPath())
|
||||
paths.Add(l.AccessPath, l.FullNestedPath())
|
||||
}
|
||||
paths.Remove("")
|
||||
return paths.List()
|
||||
|
||||
@@ -433,6 +433,23 @@ func TestCatalog_MergeRecords(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestCatalog_PackagesByPath_nestedPackagesAreNotFoundByTheOuterArchive(t *testing.T) {
|
||||
jar := Package{Name: "jar", Type: JavaPkg, Locations: file.NewLocationSet(file.NewLocation("/opt/x.jar"))}
|
||||
nested := file.Coordinates{RealPath: "/opt/x.jar", FullPath: "/opt/x.jar!/lib/a.so"}
|
||||
so := Package{Name: "so", Type: BinaryPkg, Locations: file.NewLocationSet(file.NewLocationFromCoordinates(nested))}
|
||||
c := NewCollection(jar, so)
|
||||
|
||||
names := func(pkgs []Package) []string {
|
||||
var out []string
|
||||
for _, p := range pkgs {
|
||||
out = append(out, p.Name)
|
||||
}
|
||||
return out
|
||||
}
|
||||
assert.Equal(t, []string{"jar"}, names(c.PackagesByPath("/opt/x.jar")))
|
||||
assert.Equal(t, []string{"so"}, names(c.PackagesByPath(nested.FullPath)))
|
||||
}
|
||||
|
||||
func TestCatalog_EnumerateNilCatalog(t *testing.T) {
|
||||
var c *Collection
|
||||
assert.Empty(t, c.Enumerate())
|
||||
|
||||
Reference in New Issue
Block a user