1948-filter-pkg-by-type (#2011)

---------

Signed-off-by: Christopher Phillips <christopher.phillips@anchore.com>
This commit is contained in:
Christopher Angelo Phillips 2023-08-09 16:05:52 -04:00 committed by GitHub
parent 6bf6f85584
commit 541c8d339b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 39 additions and 45 deletions

View File

@ -484,7 +484,7 @@ exclude: []
# allows users to exclude synthetic binary packages from the sbom # allows users to exclude synthetic binary packages from the sbom
# these packages are removed if an overlap with a non-synthetic package is found # these packages are removed if an overlap with a non-synthetic package is found
exclude-overlap-by-ownership: true exclude-binary-overlap-by-ownership: true
# os and/or architecture to use when referencing container images (e.g. "windows/armv6" or "arm64") # os and/or architecture to use when referencing container images (e.g. "windows/armv6" or "arm64")
# same as --platform; SYFT_PLATFORM env var # same as --platform; SYFT_PLATFORM env var

View File

@ -79,7 +79,7 @@ func CatalogPackages(src source.Source, cfg cataloger.Config) (*pkg.Collection,
// https://github.com/anchore/syft/issues/931 // https://github.com/anchore/syft/issues/931
if cfg.ExcludeBinaryOverlapByOwnership { if cfg.ExcludeBinaryOverlapByOwnership {
for _, r := range relationships { for _, r := range relationships {
if cataloger.Exclude(r, catalog) { if cataloger.ExcludeBinaryByFileOwnershipOverlap(r, catalog) {
catalog.Delete(r.To.ID()) catalog.Delete(r.To.ID())
relationships = removeRelationshipsByID(relationships, r.To.ID()) relationships = removeRelationshipsByID(relationships, r.To.ID())
} }

View File

@ -5,9 +5,9 @@ import (
"github.com/anchore/syft/syft/pkg/cataloger/generic" "github.com/anchore/syft/syft/pkg/cataloger/generic"
) )
const CatalogerName = "alpmdb-cataloger" const catalogerName = "alpmdb-cataloger"
func NewAlpmdbCataloger() *generic.Cataloger { func NewAlpmdbCataloger() *generic.Cataloger {
return generic.NewCataloger(CatalogerName). return generic.NewCataloger(catalogerName).
WithParserByGlobs(parseAlpmDB, pkg.AlpmDBGlob) WithParserByGlobs(parseAlpmDB, pkg.AlpmDBGlob)
} }

View File

@ -8,10 +8,10 @@ import (
"github.com/anchore/syft/syft/pkg/cataloger/generic" "github.com/anchore/syft/syft/pkg/cataloger/generic"
) )
const CatalogerName = "apkdb-cataloger" const catalogerName = "apkdb-cataloger"
// NewApkdbCataloger returns a new Alpine DB cataloger object. // NewApkdbCataloger returns a new Alpine DB cataloger object.
func NewApkdbCataloger() *generic.Cataloger { func NewApkdbCataloger() *generic.Cataloger {
return generic.NewCataloger(CatalogerName). return generic.NewCataloger(catalogerName).
WithParserByGlobs(parseApkDB, pkg.ApkDBGlob) WithParserByGlobs(parseApkDB, pkg.ApkDBGlob)
} }

View File

@ -7,7 +7,7 @@ import (
"github.com/anchore/syft/syft/pkg" "github.com/anchore/syft/syft/pkg"
) )
const CatalogerName = "binary-cataloger" const catalogerName = "binary-cataloger"
func NewCataloger() *Cataloger { func NewCataloger() *Cataloger {
return &Cataloger{} return &Cataloger{}
@ -22,7 +22,7 @@ type Cataloger struct{}
// Name returns a string that uniquely describes the Cataloger // Name returns a string that uniquely describes the Cataloger
func (c Cataloger) Name() string { func (c Cataloger) Name() string {
return CatalogerName return catalogerName
} }
// Catalog is given an object to resolve file references and content, this function returns any discovered Packages // Catalog is given an object to resolve file references and content, this function returns any discovered Packages

View File

@ -31,7 +31,7 @@ func newPackage(classifier classifier, location file.Location, matchMetadata map
), ),
Type: pkg.BinaryPkg, Type: pkg.BinaryPkg,
CPEs: cpes, CPEs: cpes,
FoundBy: CatalogerName, FoundBy: catalogerName,
MetadataType: pkg.BinaryMetadataType, MetadataType: pkg.BinaryMetadataType,
Metadata: pkg.BinaryMetadata{ Metadata: pkg.BinaryMetadata{
Matches: []pkg.ClassifierMatch{ Matches: []pkg.ClassifierMatch{

View File

@ -7,11 +7,11 @@ import (
"github.com/anchore/syft/syft/pkg/cataloger/generic" "github.com/anchore/syft/syft/pkg/cataloger/generic"
) )
const CatalogerName = "dpkgdb-cataloger" const catalogerName = "dpkgdb-cataloger"
// NewDpkgdbCataloger returns a new Deb package cataloger capable of parsing DPKG status DB files. // NewDpkgdbCataloger returns a new Deb package cataloger capable of parsing DPKG status DB files.
func NewDpkgdbCataloger() *generic.Cataloger { func NewDpkgdbCataloger() *generic.Cataloger {
return generic.NewCataloger(CatalogerName). return generic.NewCataloger(catalogerName).
// note: these globs have been intentionally split up in order to improve search performance, // note: these globs have been intentionally split up in order to improve search performance,
// please do NOT combine into: "**/var/lib/dpkg/{status,status.d/*}" // please do NOT combine into: "**/var/lib/dpkg/{status,status.d/*}"
WithParserByGlobs(parseDpkgDB, "**/var/lib/dpkg/status", "**/var/lib/dpkg/status.d/*", "**/lib/opkg/info/*.control", "**/lib/opkg/status") WithParserByGlobs(parseDpkgDB, "**/var/lib/dpkg/status", "**/var/lib/dpkg/status.d/*", "**/lib/opkg/info/*.control", "**/lib/opkg/status")

View File

@ -12,7 +12,7 @@ import (
) )
const ( const (
CatalogerName = "nix-store-cataloger" catalogerName = "nix-store-cataloger"
nixStoreGlob = "**/nix/store/*" nixStoreGlob = "**/nix/store/*"
) )
@ -24,7 +24,7 @@ func NewStoreCataloger() *StoreCataloger {
} }
func (c *StoreCataloger) Name() string { func (c *StoreCataloger) Name() string {
return CatalogerName return catalogerName
} }
func (c *StoreCataloger) Catalog(resolver file.Resolver) ([]pkg.Package, []artifact.Relationship, error) { func (c *StoreCataloger) Catalog(resolver file.Resolver) ([]pkg.Package, []artifact.Relationship, error) {

View File

@ -24,7 +24,7 @@ func TestCataloger_Catalog(t *testing.T) {
Version: "2.34-210", Version: "2.34-210",
PURL: "pkg:nix/glibc@2.34-210?output=bin&outputhash=h0cnbmfcn93xm5dg2x27ixhag1cwndga", PURL: "pkg:nix/glibc@2.34-210?output=bin&outputhash=h0cnbmfcn93xm5dg2x27ixhag1cwndga",
Locations: file.NewLocationSet(file.NewLocation("nix/store/h0cnbmfcn93xm5dg2x27ixhag1cwndga-glibc-2.34-210-bin")), Locations: file.NewLocationSet(file.NewLocation("nix/store/h0cnbmfcn93xm5dg2x27ixhag1cwndga-glibc-2.34-210-bin")),
FoundBy: CatalogerName, FoundBy: catalogerName,
Type: pkg.NixPkg, Type: pkg.NixPkg,
MetadataType: pkg.NixStoreMetadataType, MetadataType: pkg.NixStoreMetadataType,
Metadata: pkg.NixStoreMetadata{ Metadata: pkg.NixStoreMetadata{

View File

@ -10,7 +10,7 @@ func newNixStorePackage(storePath nixStorePath, locations ...file.Location) pkg.
p := pkg.Package{ p := pkg.Package{
Name: storePath.name, Name: storePath.name,
Version: storePath.version, Version: storePath.version,
FoundBy: CatalogerName, FoundBy: catalogerName,
Locations: file.NewLocationSet(locations...), Locations: file.NewLocationSet(locations...),
Type: pkg.NixPkg, Type: pkg.NixPkg,
PURL: packageURL(storePath), PURL: packageURL(storePath),

View File

@ -5,33 +5,29 @@ import (
"github.com/anchore/syft/syft/artifact" "github.com/anchore/syft/syft/artifact"
"github.com/anchore/syft/syft/pkg" "github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/pkg/cataloger/alpm"
"github.com/anchore/syft/syft/pkg/cataloger/apkdb"
"github.com/anchore/syft/syft/pkg/cataloger/binary"
"github.com/anchore/syft/syft/pkg/cataloger/deb"
"github.com/anchore/syft/syft/pkg/cataloger/nix"
"github.com/anchore/syft/syft/pkg/cataloger/rpm"
) )
var ( var (
osCatalogerTypes = []string{ osCatalogerTypes = []pkg.Type{
apkdb.CatalogerName, pkg.AlpmPkg,
alpm.CatalogerName, pkg.ApkPkg,
deb.CatalogerName, pkg.DebPkg,
nix.CatalogerName, pkg.NixPkg,
rpm.DBCatalogerName, pkg.PortagePkg,
rpm.FileCatalogerName, pkg.RpmPkg,
}
binaryCatalogerTypes = []pkg.Type{
pkg.BinaryPkg,
} }
binaryCatalogerTypes = []string{binary.CatalogerName}
) )
// Exclude will remove packages from a collection given the following properties are true // ExcludeBinaryByFileOwnershipOverlap will remove packages from a collection given the following properties are true
// 1) the relationship between packages is OwnershipByFileOverlap // 1) the relationship between packages is OwnershipByFileOverlap
// 2) the parent is an "os" package // 2) the parent is an "os" package
// 3) the child is a synthetic package generated by the binary cataloger // 3) the child is a synthetic package generated by the binary cataloger
// 4) the package names are identical // 4) the package names are identical
// This exclude was implemented as a way to help resolve: https://github.com/anchore/syft/issues/931 // This was implemented as a way to help resolve: https://github.com/anchore/syft/issues/931
func Exclude(r artifact.Relationship, c *pkg.Collection) bool { func ExcludeBinaryByFileOwnershipOverlap(r artifact.Relationship, c *pkg.Collection) bool {
if artifact.OwnershipByFileOverlapRelationship != r.Type { if artifact.OwnershipByFileOverlapRelationship != r.Type {
return false return false
} }
@ -41,7 +37,7 @@ func Exclude(r artifact.Relationship, c *pkg.Collection) bool {
return false return false
} }
parentInExclusion := slices.Contains(osCatalogerTypes, parent.FoundBy) parentInExclusion := slices.Contains(osCatalogerTypes, parent.Type)
if !parentInExclusion { if !parentInExclusion {
return false return false
} }
@ -51,5 +47,5 @@ func Exclude(r artifact.Relationship, c *pkg.Collection) bool {
return false return false
} }
return slices.Contains(binaryCatalogerTypes, child.FoundBy) return slices.Contains(binaryCatalogerTypes, child.Type)
} }

View File

@ -5,15 +5,13 @@ import (
"github.com/anchore/syft/syft/artifact" "github.com/anchore/syft/syft/artifact"
"github.com/anchore/syft/syft/pkg" "github.com/anchore/syft/syft/pkg"
"github.com/anchore/syft/syft/pkg/cataloger/apkdb"
"github.com/anchore/syft/syft/pkg/cataloger/binary"
) )
func TestExclude(t *testing.T) { func TestExclude(t *testing.T) {
packageA := pkg.Package{Name: "package-a", Type: pkg.ApkPkg, FoundBy: apkdb.CatalogerName} packageA := pkg.Package{Name: "package-a", Type: pkg.ApkPkg}
packageB := pkg.Package{Name: "package-a", Type: pkg.PythonPkg, FoundBy: "language-cataloger"} packageB := pkg.Package{Name: "package-a", Type: pkg.PythonPkg}
packageC := pkg.Package{Name: "package-a", Type: pkg.BinaryPkg, FoundBy: binary.CatalogerName} packageC := pkg.Package{Name: "package-a", Type: pkg.BinaryPkg}
packageD := pkg.Package{Name: "package-d", Type: pkg.BinaryPkg, FoundBy: binary.CatalogerName} packageD := pkg.Package{Name: "package-d", Type: pkg.BinaryPkg}
for _, p := range []*pkg.Package{&packageA, &packageB, &packageC, &packageD} { for _, p := range []*pkg.Package{&packageA, &packageB, &packageC, &packageD} {
p := p p := p
p.SetID() p.SetID()
@ -69,7 +67,7 @@ func TestExclude(t *testing.T) {
for _, test := range tests { for _, test := range tests {
t.Run(test.name, func(t *testing.T) { t.Run(test.name, func(t *testing.T) {
if !Exclude(test.relationship, test.packages) && test.shouldExclude { if !ExcludeBinaryByFileOwnershipOverlap(test.relationship, test.packages) && test.shouldExclude {
t.Errorf("expected to exclude relationship %+v", test.relationship) t.Errorf("expected to exclude relationship %+v", test.relationship)
} }
}) })

View File

@ -12,8 +12,8 @@ import (
) )
const ( const (
DBCatalogerName = "rpm-db-cataloger" dbCatalogerName = "rpm-db-cataloger"
FileCatalogerName = "rpm-file-cataloger" fileCatalogerName = "rpm-file-cataloger"
) )
// NewRpmDBCataloger returns a new RPM DB cataloger object. // NewRpmDBCataloger returns a new RPM DB cataloger object.
@ -23,14 +23,14 @@ func NewRpmDBCataloger() *generic.Cataloger {
log.Warnf("sqlite driver is not available, newer RPM databases might not be cataloged") log.Warnf("sqlite driver is not available, newer RPM databases might not be cataloged")
} }
return generic.NewCataloger(DBCatalogerName). return generic.NewCataloger(dbCatalogerName).
WithParserByGlobs(parseRpmDB, pkg.RpmDBGlob). WithParserByGlobs(parseRpmDB, pkg.RpmDBGlob).
WithParserByGlobs(parseRpmManifest, pkg.RpmManifestGlob) WithParserByGlobs(parseRpmManifest, pkg.RpmManifestGlob)
} }
// NewFileCataloger returns a new RPM file cataloger object. // NewFileCataloger returns a new RPM file cataloger object.
func NewFileCataloger() *generic.Cataloger { func NewFileCataloger() *generic.Cataloger {
return generic.NewCataloger(FileCatalogerName). return generic.NewCataloger(fileCatalogerName).
WithParserByGlobs(parseRpm, "**/*.rpm") WithParserByGlobs(parseRpm, "**/*.rpm")
} }