diff --git a/.golangci.yaml b/.golangci.yaml index 89098f7c0..927d1d47a 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -1,9 +1,12 @@ -# TODO: enable this when we have coverage on docstring comments -#issues: +issues: + max-same-issues: 25 + + # TODO: enable this when we have coverage on docstring comments # # The list of ids of default excludes to include or disable. # include: # - EXC0002 # disable excluding of issues about comments from golint + linters: # inverted configuration with `enable-all` and `disable` is not scalable during updates of golangci-lint disable-all: true @@ -15,6 +18,7 @@ linters: - errcheck - errorlint - exportloopref + - forcetypeassert - funlen - gocognit - goconst diff --git a/schema/spdx-json/spdx-schema-2.3.json b/schema/spdx-json/spdx-schema-2.3.json index 805b11d0b..ee66afa1c 100644 --- a/schema/spdx-json/spdx-schema-2.3.json +++ b/schema/spdx-json/spdx-schema-2.3.json @@ -366,10 +366,10 @@ "type" : "string" }, "licenseInfoFromFiles" : { - "description" : "The licensing information that was discovered directly within the package. There will be an instance of this property for each distinct value of alllicenseInfoInFile properties of all files contained in the package.\n\nIf the licenseInfoFromFiles field is not present for a package and filesAnalyzed property for that same pacakge is true or omitted, it implies an equivalent meaning to NOASSERTION.", + "description" : "The licensing information that was discovered directly within the package. There will be an instance of this property for each distinct value of alllicenseInfoInFile properties of all files contained in the package.\n\nIf the licenseInfoFromFiles field is not present for a package and filesAnalyzed property for that same package is true or omitted, it implies an equivalent meaning to NOASSERTION.", "type" : "array", "items" : { - "description" : "License expression for licenseInfoFromFiles. See SPDX Annex D for the license expression syntax. The licensing information that was discovered directly within the package. There will be an instance of this property for each distinct value of alllicenseInfoInFile properties of all files contained in the package.\n\nIf the licenseInfoFromFiles field is not present for a package and filesAnalyzed property for that same pacakge is true or omitted, it implies an equivalent meaning to NOASSERTION.", + "description" : "License expression for licenseInfoFromFiles. See SPDX Annex D for the license expression syntax. The licensing information that was discovered directly within the package. There will be an instance of this property for each distinct value of alllicenseInfoInFile properties of all files contained in the package.\n\nIf the licenseInfoFromFiles field is not present for a package and filesAnalyzed property for that same package is true or omitted, it implies an equivalent meaning to NOASSERTION.", "type" : "string" } }, diff --git a/syft/formats/syftjson/to_syft_model.go b/syft/formats/syftjson/to_syft_model.go index 14baab89e..c69bd8558 100644 --- a/syft/formats/syftjson/to_syft_model.go +++ b/syft/formats/syftjson/to_syft_model.go @@ -145,22 +145,37 @@ func toSyftDescriptor(d model.Descriptor) sbom.Descriptor { func toSyftSourceData(s model.Source) *source.Metadata { switch s.Type { case "directory": + path, ok := s.Target.(string) + if !ok { + log.Warnf("unable to parse source target as string: %+v", s.Target) + return nil + } return &source.Metadata{ ID: s.ID, Scheme: source.DirectoryScheme, - Path: s.Target.(string), + Path: path, } case "file": + path, ok := s.Target.(string) + if !ok { + log.Warnf("unable to parse source target as string: %+v", s.Target) + return nil + } return &source.Metadata{ ID: s.ID, Scheme: source.FileScheme, - Path: s.Target.(string), + Path: path, } case "image": + metadata, ok := s.Target.(source.ImageMetadata) + if !ok { + log.Warnf("unable to parse source target as image metadata: %+v", s.Target) + return nil + } return &source.Metadata{ ID: s.ID, Scheme: source.ImageScheme, - ImageMetadata: s.Target.(source.ImageMetadata), + ImageMetadata: metadata, } } return nil diff --git a/syft/pkg/cataloger/deb/package.go b/syft/pkg/cataloger/deb/package.go index 2190e2b23..8ef890b17 100644 --- a/syft/pkg/cataloger/deb/package.go +++ b/syft/pkg/cataloger/deb/package.go @@ -81,7 +81,11 @@ func packageURL(m pkg.DpkgMetadata, distro *linux.Release) string { } func addLicenses(resolver source.FileResolver, dbLocation source.Location, p *pkg.Package) { - metadata := p.Metadata.(pkg.DpkgMetadata) + metadata, ok := p.Metadata.(pkg.DpkgMetadata) + if !ok { + log.WithFields("package", p.String()).Warn("unable to extract DPKG metadata to add licenses") + return + } // get license information from the copyright file copyrightReader, copyrightLocation := fetchCopyrightContents(resolver, dbLocation, metadata) @@ -97,7 +101,11 @@ func addLicenses(resolver source.FileResolver, dbLocation source.Location, p *pk } func mergeFileListing(resolver source.FileResolver, dbLocation source.Location, p *pkg.Package) { - metadata := p.Metadata.(pkg.DpkgMetadata) + metadata, ok := p.Metadata.(pkg.DpkgMetadata) + if !ok { + log.WithFields("package", p.String()).Warn("unable to extract DPKG metadata to file listing") + return + } // get file listing (package files + additional config files) files, infoLocations := getAdditionalFileListing(resolver, dbLocation, metadata) diff --git a/syft/pkg/cataloger/erlang/parse_rebar_lock.go b/syft/pkg/cataloger/erlang/parse_rebar_lock.go index 97e092947..fc0331b3a 100644 --- a/syft/pkg/cataloger/erlang/parse_rebar_lock.go +++ b/syft/pkg/cataloger/erlang/parse_rebar_lock.go @@ -7,6 +7,7 @@ import ( "io" "regexp" + "github.com/anchore/syft/internal/log" "github.com/anchore/syft/syft/artifact" "github.com/anchore/syft/syft/pkg" "github.com/anchore/syft/syft/pkg/cataloger/generic" @@ -42,7 +43,12 @@ loop: if len(tokens) < 5 { name, hash := tokens[1], tokens[2] sourcePkg := pkgMap[name] - metadata := sourcePkg.Metadata.(pkg.RebarLockMetadata) + metadata, ok := sourcePkg.Metadata.(pkg.RebarLockMetadata) + if !ok { + log.WithFields("package", name).Warn("unable to extract rebar.lock metadata to add hash metadata") + continue + } + if metadata.PkgHash == "" { metadata.PkgHash = hash } else { diff --git a/syft/pkg/cataloger/java/archive_parser.go b/syft/pkg/cataloger/java/archive_parser.go index e1b03b437..d9e746e6e 100644 --- a/syft/pkg/cataloger/java/archive_parser.go +++ b/syft/pkg/cataloger/java/archive_parser.go @@ -134,7 +134,11 @@ func (j *archiveParser) parse() ([]pkg.Package, []artifact.Relationship, error) // note: since package information may change after initial creation when parsing multiple locations within the // jar, we wait until the conclusion of the parsing process before synthesizing pURLs. for i, p := range pkgs { - pkgs[i].PURL = packageURL(p.Name, p.Version, p.Metadata.(pkg.JavaMetadata)) + if m, ok := p.Metadata.(pkg.JavaMetadata); ok { + pkgs[i].PURL = packageURL(p.Name, p.Version, m) + } else { + log.WithFields("package", p.String()).Warn("unable to extract java metadata to generate purl") + } } return pkgs, relationships, nil @@ -401,10 +405,20 @@ func packageIdentitiesMatch(p pkg.Package, parentPkg *pkg.Package) bool { return true } - metadata := p.Metadata.(pkg.JavaMetadata) + metadata, ok := p.Metadata.(pkg.JavaMetadata) + if !ok { + log.WithFields("package", p.String()).Warn("unable to extract java metadata to check for matching package identity") + return false + } + + parentMetadata, ok := parentPkg.Metadata.(pkg.JavaMetadata) + if !ok { + log.WithFields("package", p.String()).Warn("unable to extract java metadata from parent for verifying virtual path") + return false + } // the virtual path matches... - if parentPkg.Metadata.(pkg.JavaMetadata).VirtualPath == metadata.VirtualPath { + if parentMetadata.VirtualPath == metadata.VirtualPath { return true } diff --git a/ui/event_handlers.go b/ui/event_handlers.go index 3d4da4cdc..49e5cccd3 100644 --- a/ui/event_handlers.go +++ b/ui/event_handlers.go @@ -604,7 +604,10 @@ func AttestationStartedHandler(ctx context.Context, fr *frame.Frame, event party line, _ := fr.Append() if l.Len() > 5 { elem := l.Front() - line := elem.Value.(*frame.Line) + line, ok := elem.Value.(*frame.Line) + if !ok { + continue + } err = line.Remove() if err != nil { return @@ -627,7 +630,10 @@ func AttestationStartedHandler(ctx context.Context, fr *frame.Frame, event party if !failed { // roll up logs into completed status (only if successful) for e := l.Back(); e != nil; e = e.Prev() { - line := e.Value.(*frame.Line) + line, ok := e.Value.(*frame.Line) + if !ok { + continue + } err = line.Remove() if err != nil { return