ignore apk xattr file checksum + remove log.Errorf error wraps (#192)

Signed-off-by: Alex Goodman <alex.goodman@anchore.com>
This commit is contained in:
Alex Goodman 2020-09-28 17:22:17 -04:00 committed by GitHub
parent 4b78d9a1c0
commit 26855a2a9e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 85 additions and 7 deletions

View file

@ -47,7 +47,7 @@ func NewZipFileManifest(archivePath string) (ZipFileManifest, error) {
defer func() { defer func() {
err = zipReader.Close() err = zipReader.Close()
if err != nil { if err != nil {
log.Errorf("unable to close zip archive (%s): %w", archivePath, err) log.Errorf("unable to close zip archive (%s): %+v", archivePath, err)
} }
}() }()

View file

@ -43,7 +43,7 @@ func TraverseFilesInZip(archivePath string, visitor func(*zip.File) error, paths
defer func() { defer func() {
err = zipReader.Close() err = zipReader.Close()
if err != nil { if err != nil {
log.Errorf("unable to close zip archive (%s): %w", archivePath, err) log.Errorf("unable to close zip archive (%s): %+v", archivePath, err)
} }
}() }()

View file

@ -93,7 +93,7 @@ func parseApkDBEntry(reader io.Reader) (*pkg.ApkMetadata, error) {
fileRecord = &files[len(files)-1] fileRecord = &files[len(files)-1]
case "a": case "a":
ownershipFields := strings.Split(value, ":") ownershipFields := strings.Split(value, ":")
if len(ownershipFields) != 3 { if len(ownershipFields) < 3 {
log.Errorf("unexpected APK ownership field: %q", value) log.Errorf("unexpected APK ownership field: %q", value)
continue continue
} }
@ -104,6 +104,8 @@ func parseApkDBEntry(reader io.Reader) (*pkg.ApkMetadata, error) {
fileRecord.OwnerUID = ownershipFields[0] fileRecord.OwnerUID = ownershipFields[0]
fileRecord.OwnerGUI = ownershipFields[1] fileRecord.OwnerGUI = ownershipFields[1]
fileRecord.Permissions = ownershipFields[2] fileRecord.Permissions = ownershipFields[2]
// note: there are more optional fields available that we are not capturing, e.g.:
// "0:0:755:Q1JaDEHQHBbizhEzoWK1YxuraNU/4="
case "Z": case "Z":
if fileRecord == nil { if fileRecord == nil {
log.Errorf("checksum field with no parent record: %q", value) log.Errorf("checksum field with no parent record: %q", value)

View file

@ -10,6 +10,56 @@ import (
"github.com/anchore/syft/syft/pkg" "github.com/anchore/syft/syft/pkg"
) )
func TestExtraFileAttributes(t *testing.T) {
tests := []struct {
name string
expected pkg.ApkMetadata
}{
{
name: "test extra file attributes (checksum) are ignored",
expected: pkg.ApkMetadata{
Files: []pkg.ApkFileRecord{
{
Path: "/usr/lib/jvm/java-1.8-openjdk/bin/policytool",
OwnerUID: "0",
OwnerGUI: "0",
Permissions: "755",
Checksum: "Q1M0C9qfC/+kdRiOodeihG2GMRtkE=",
},
},
},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
file, err := os.Open("test-fixtures/extra-file-attributes")
if err != nil {
t.Fatal("Unable to read test-fixtures/extra-file-attributes: ", err)
}
defer func() {
err := file.Close()
if err != nil {
t.Fatal("closing file failed:", err)
}
}()
reader := bufio.NewReader(file)
entry, err := parseApkDBEntry(reader)
if err != nil {
t.Fatal("Unable to read file contents: ", err)
}
if diff := deep.Equal(entry.Files, test.expected.Files); diff != nil {
for _, d := range diff {
t.Errorf("diff: %+v", d)
}
}
})
}
}
func TestSinglePackage(t *testing.T) { func TestSinglePackage(t *testing.T) {
tests := []struct { tests := []struct {
name string name string

View file

@ -0,0 +1,22 @@
P:openjdk8-jre
V:8.212.04-r0
A:x86_64
S:359029
I:970752
T:OpenJDK 8 Java Runtime
U:https://icedtea.classpath.org/
L:custom
o:openjdk8
m:Timo Teras <timo.teras@iki.fi>
t:1556993127
c:46badd1aabd3375ae4b41c7194bc448f74b2ea4a
D:java-cacerts nss so:libX11.so.6 so:libXcomposite.so.1 so:libXext.so.6 so:libXi.so.6 so:libXrender.so.1 so:libXtst.so.6 so:libasound.so.2 so:libc.musl-x86_64.so.1 so:libfreetype.so.6 so:libgcc_s.so.1 so:libgif.so.7 so:libjpeg.so.8 so:libpng16.so.16 so:libstdc++.so.6 so:openjdk8:libawt.so so:openjdk8:libjava.so so:openjdk8:libjli.so so:openjdk8:libjvm.so
p:so:openjdk8:libawt_xawt.so=0 so:openjdk8:libfontmanager.so=0 so:openjdk8:libjawt.so=0 so:openjdk8:libjsoundalsa.so=0 so:openjdk8:libsplashscreen.so=0
F:usr
F:usr/lib
F:usr/lib/jvm
F:usr/lib/jvm/java-1.8-openjdk
F:usr/lib/jvm/java-1.8-openjdk/bin
R:policytool
a:0:0:755:Q1JaDEHQHBbizhEzoWK1YxuraNU/4=
Z:Q1M0C9qfC/+kdRiOodeihG2GMRtkE=

View file

@ -51,7 +51,7 @@ func (a *GenericCataloger) SelectFiles(resolver scope.FileResolver) []file.Refer
for path, parser := range a.pathParsers { for path, parser := range a.pathParsers {
files, err := resolver.FilesByPath(file.Path(path)) files, err := resolver.FilesByPath(file.Path(path))
if err != nil { if err != nil {
log.Errorf("cataloger failed to select files by path: %w", err) log.Errorf("cataloger failed to select files by path: %+v", err)
} }
if files != nil { if files != nil {
a.register(files, parser) a.register(files, parser)
@ -88,7 +88,7 @@ func (a *GenericCataloger) Catalog(contents map[file.Reference]string, upstreamM
entries, err := parser(string(reference.Path), strings.NewReader(content)) entries, err := parser(string(reference.Path), strings.NewReader(content))
if err != nil { if err != nil {
// TODO: should we fail? or only log? // TODO: should we fail? or only log?
log.Errorf("cataloger '%s' failed to parse entries (reference=%+v): %w", upstreamMatcher, reference, err) log.Errorf("cataloger '%s' failed to parse entries (reference=%+v): %+v", upstreamMatcher, reference, err)
continue continue
} }

View file

@ -19,7 +19,7 @@ func saveArchiveToTmp(reader io.Reader) (string, string, func(), error) {
cleanupFn := func() { cleanupFn := func() {
err = os.RemoveAll(tempDir) err = os.RemoveAll(tempDir)
if err != nil { if err != nil {
log.Errorf("unable to cleanup jar tempdir: %w", err) log.Errorf("unable to cleanup jar tempdir: %+v", err)
} }
} }

View file

@ -4,7 +4,11 @@ import (
"github.com/package-url/packageurl-go" "github.com/package-url/packageurl-go"
) )
// ApkMetadata represents all captured data for a Alpine DB package entry. See https://wiki.alpinelinux.org/wiki/Apk_spec for more information. // ApkMetadata represents all captured data for a Alpine DB package entry.
// See the following sources for more information:
// - https://wiki.alpinelinux.org/wiki/Apk_spec
// - https://git.alpinelinux.org/apk-tools/tree/src/package.c
// - https://git.alpinelinux.org/apk-tools/tree/src/database.c
type ApkMetadata struct { type ApkMetadata struct {
Package string `mapstructure:"P" json:"package"` Package string `mapstructure:"P" json:"package"`
OriginPackage string `mapstructure:"o" json:"originPackage"` OriginPackage string `mapstructure:"o" json:"originPackage"`