mirror of
https://github.com/anchore/syft.git
synced 2026-10-31 06:26:30 +01:00
121 lines
4.9 KiB
Go
121 lines
4.9 KiB
Go
package task
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/anchore/syft/syft/artifact"
|
|
"github.com/anchore/syft/syft/cataloging"
|
|
"github.com/anchore/syft/syft/file"
|
|
"github.com/anchore/syft/syft/pkg"
|
|
"github.com/anchore/syft/syft/sbom"
|
|
)
|
|
|
|
func Test_unknownsLabeler_archiveReasonsSurvivePackages(t *testing.T) {
|
|
jar := file.NewCoordinates("/app.jar", "")
|
|
p := pkg.Package{Name: "app", Locations: file.NewLocationSet(file.NewLocationFromCoordinates(jar))}
|
|
p.SetID()
|
|
s := &sbom.SBOM{Artifacts: sbom.Artifacts{
|
|
Packages: pkg.NewCollection(p),
|
|
Unknowns: map[file.Coordinates][]string{jar: {
|
|
formatUnknown("archive cataloged from part of its contents: too big", ArchiveCatalogerTaskName),
|
|
formatUnknown("unable to read manifest", "java-archive-cataloger"),
|
|
}},
|
|
}}
|
|
|
|
unknownsLabelerTask{cataloging.UnknownsConfig{RemoveWhenPackagesDefined: true}}.finalize(file.NewMockResolverForPaths(), s)
|
|
|
|
assert.Equal(t, []string{formatUnknown("archive cataloged from part of its contents: too big", ArchiveCatalogerTaskName)}, s.Artifacts.Unknowns[jar],
|
|
"a package describing the archive explains a parse failure, not contents left out")
|
|
}
|
|
|
|
func Test_unknownsLabeler_archiveContentsAreReportedByFullPath(t *testing.T) {
|
|
// a package describing an archive does not account for the files within it
|
|
war := file.NewCoordinates("/app.war", "layer")
|
|
in := func(fullPath string) file.Coordinates {
|
|
return file.Coordinates{RealPath: "/app.war", FileSystemID: "layer", FullPath: fullPath}
|
|
}
|
|
nativeLib := in("/app.war!/WEB-INF/lib/jna.jar!/linux-x86-64/libjnidispatch.so")
|
|
unidentifiedJar := in("/app.war!/WEB-INF/lib/javax.inject-1.jar")
|
|
p := pkg.Package{Name: "app", Locations: file.NewLocationSet(file.NewLocationFromCoordinates(war))}
|
|
p.SetID()
|
|
noPackage := formatUnknown("no package identified in archive", "java-archive-cataloger")
|
|
|
|
s := &sbom.SBOM{
|
|
Artifacts: sbom.Artifacts{
|
|
Packages: pkg.NewCollection(p),
|
|
Executables: map[file.Coordinates]file.Executable{nativeLib: {}},
|
|
Unknowns: map[file.Coordinates][]string{unidentifiedJar: {noPackage}},
|
|
},
|
|
Relationships: []artifact.Relationship{{From: war, To: unidentifiedJar, Type: artifact.ContainsRelationship}},
|
|
}
|
|
|
|
unknownsLabelerTask{cataloging.UnknownsConfig{RemoveWhenPackagesDefined: true, IncludeExecutablesWithoutPackages: true}}.finalize(file.NewMockResolverForPaths(), s)
|
|
|
|
assert.Equal(t, map[file.Coordinates][]string{
|
|
nativeLib: {formatUnknown("no package identified in executable file", unknownsLabelerTaskName)},
|
|
unidentifiedJar: {noPackage},
|
|
}, s.Artifacts.Unknowns)
|
|
}
|
|
|
|
func Test_unknownsLabeler_relativeOwnedPathsNameNothingInAnArchive(t *testing.T) {
|
|
// a python RECORD lists paths relative to site-packages, which resolve nowhere at the scan root either
|
|
whl := func(fullPath string) file.Coordinates {
|
|
return file.Coordinates{RealPath: "/pip.whl", FullPath: fullPath}
|
|
}
|
|
tool := whl("/pip.whl!/pip/tool")
|
|
p := pkg.Package{
|
|
Name: "pip",
|
|
Locations: file.NewLocationSet(file.NewLocationFromCoordinates(whl("/pip.whl!/pip.dist-info/METADATA"))),
|
|
Metadata: pkg.PythonPackage{Files: []pkg.PythonFileRecord{{Path: "pip/tool"}}},
|
|
}
|
|
p.SetID()
|
|
s := &sbom.SBOM{Artifacts: sbom.Artifacts{
|
|
Packages: pkg.NewCollection(p),
|
|
Executables: map[file.Coordinates]file.Executable{tool: {}},
|
|
}}
|
|
|
|
unknownsLabelerTask{cataloging.UnknownsConfig{IncludeExecutablesWithoutPackages: true}}.finalize(file.NewMockResolverForPaths(), s)
|
|
|
|
assert.NotEmpty(t, s.Artifacts.Unknowns[tool])
|
|
}
|
|
|
|
func Test_unknownsLabeler_ownedFilesAreWithinTheOwnersContainer(t *testing.T) {
|
|
atRoot := file.NewCoordinates("/usr/bin/foo", "")
|
|
inArchive := file.Coordinates{RealPath: "/rootfs.tar", FullPath: "/rootfs.tar!/usr/bin/foo"}
|
|
owner := func(at file.Coordinates) pkg.Package {
|
|
p := pkg.Package{
|
|
Name: "owner",
|
|
Type: pkg.RpmPkg,
|
|
Locations: file.NewLocationSet(file.NewLocationFromCoordinates(at)),
|
|
Metadata: pkg.RpmDBEntry{Files: []pkg.RpmFileRecord{{Path: "/usr/bin/foo"}}},
|
|
}
|
|
p.SetID()
|
|
return p
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
owner file.Coordinates
|
|
referenced file.Coordinates
|
|
}{
|
|
{name: "an owner at the scan root", owner: file.NewCoordinates("/var/lib/rpm/Packages", ""), referenced: atRoot},
|
|
{name: "an owner inside an archive", owner: file.Coordinates{RealPath: "/rootfs.tar", FullPath: "/rootfs.tar!/var/lib/rpm/Packages"}, referenced: inArchive},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
s := &sbom.SBOM{Artifacts: sbom.Artifacts{
|
|
Packages: pkg.NewCollection(owner(tt.owner)),
|
|
Executables: map[file.Coordinates]file.Executable{atRoot: {}, inArchive: {}},
|
|
}}
|
|
|
|
unknownsLabelerTask{cataloging.UnknownsConfig{IncludeExecutablesWithoutPackages: true}}.finalize(file.NewMockResolverForPaths("/usr/bin/foo"), s)
|
|
|
|
for _, exe := range []file.Coordinates{atRoot, inArchive} {
|
|
assert.Equal(t, exe != tt.referenced, len(s.Artifacts.Unknowns[exe]) > 0, exe.FullNestedPath())
|
|
}
|
|
})
|
|
}
|
|
}
|