feat: report unknowns in sbom (#2998)

Signed-off-by: Keith Zantow <kzantow@gmail.com>
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
Co-authored-by: Alex Goodman <wagoodman@users.noreply.github.com>
This commit is contained in:
Keith Zantow
2024-10-07 16:11:37 -04:00
committed by GitHub
co-authored by Alex Goodman
parent 4d7ed9f749
commit ccbee94b87
145 changed files with 4420 additions and 233 deletions
@@ -11,7 +11,6 @@ import (
"github.com/mitchellh/mapstructure"
"github.com/anchore/syft/internal"
"github.com/anchore/syft/internal/log"
"github.com/anchore/syft/syft/artifact"
"github.com/anchore/syft/syft/file"
"github.com/anchore/syft/syft/pkg"
@@ -64,11 +63,8 @@ func parsePackageJSON(_ context.Context, _ file.Resolver, _ *generic.Environment
return nil, nil, fmt.Errorf("failed to parse package.json file: %w", err)
}
if !p.hasNameAndVersionValues() {
log.Debugf("encountered package.json file without a name and/or version field, ignoring (path=%q)", reader.Path())
return nil, nil, nil
}
// always create a package, regardless of having a valid name and/or version,
// a compliance filter later will remove these packages based on compliance rules
pkgs = append(
pkgs,
newPackageJSONPackage(p, reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation)),
@@ -203,10 +199,6 @@ func licensesFromJSON(b []byte) ([]npmPackageLicense, error) {
return nil, errors.New("unmarshal failed")
}
func (p packageJSON) hasNameAndVersionValues() bool {
return p.Name != "" && p.Version != ""
}
// this supports both windows and unix paths
var filepathSeparator = regexp.MustCompile(`[\\/]`)
@@ -210,10 +210,28 @@ func TestParsePackageJSON(t *testing.T) {
}
}
func Test_corruptPackageJSON(t *testing.T) {
pkgtest.NewCatalogTester().
FromFile(t, "test-fixtures/corrupt/package.json").
WithError().
TestParser(t, parsePackageJSON)
}
func TestParsePackageJSON_Partial(t *testing.T) { // see https://github.com/anchore/syft/issues/311
const fixtureFile = "test-fixtures/pkg-json/package-partial.json"
pkgtest.TestFileParser(t, fixtureFile, parsePackageJSON, nil, nil)
// raise package.json files as packages with any information we find, these will be filtered out
// according to compliance rules later
expectedPkgs := []pkg.Package{
{
Language: pkg.JavaScript,
Type: pkg.NpmPkg,
PURL: packageURL("", ""),
Metadata: pkg.NpmPackage{},
Locations: file.NewLocationSet(file.NewLocation(fixtureFile)),
},
}
pkgtest.TestFileParser(t, fixtureFile, parsePackageJSON, expectedPkgs, nil)
}
func Test_pathContainsNodeModulesDirectory(t *testing.T) {
@@ -9,6 +9,7 @@ import (
"strings"
"github.com/anchore/syft/internal/log"
"github.com/anchore/syft/internal/unknown"
"github.com/anchore/syft/syft/artifact"
"github.com/anchore/syft/syft/file"
"github.com/anchore/syft/syft/pkg"
@@ -100,7 +101,7 @@ func (a genericPackageLockAdapter) parsePackageLock(_ context.Context, resolver
pkg.Sort(pkgs)
return pkgs, nil, nil
return pkgs, nil, unknown.IfEmptyf(pkgs, "unable to determine packages")
}
func (licenses *packageLockLicense) UnmarshalJSON(data []byte) (err error) {
@@ -333,3 +333,11 @@ func TestParsePackageLockLicenseWithArray(t *testing.T) {
adapter := newGenericPackageLockAdapter(CatalogerConfig{})
pkgtest.TestFileParser(t, fixture, adapter.parsePackageLock, expectedPkgs, expectedRelationships)
}
func Test_corruptPackageLock(t *testing.T) {
gap := newGenericPackageLockAdapter(DefaultCatalogerConfig())
pkgtest.NewCatalogTester().
FromFile(t, "test-fixtures/corrupt/package-lock.json").
WithError().
TestParser(t, gap.parsePackageLock)
}
@@ -11,6 +11,7 @@ import (
"gopkg.in/yaml.v3"
"github.com/anchore/syft/internal/log"
"github.com/anchore/syft/internal/unknown"
"github.com/anchore/syft/syft/artifact"
"github.com/anchore/syft/syft/file"
"github.com/anchore/syft/syft/pkg"
@@ -94,7 +95,7 @@ func parsePnpmLock(_ context.Context, resolver file.Resolver, _ *generic.Environ
pkg.Sort(pkgs)
return pkgs, nil, nil
return pkgs, nil, unknown.IfEmptyf(pkgs, "unable to determine packages")
}
func hasPkg(pkgs []pkg.Package, name, version string) bool {
@@ -144,3 +144,10 @@ func TestParsePnpmV6Lock(t *testing.T) {
pkgtest.TestFileParser(t, fixture, parsePnpmLock, expectedPkgs, expectedRelationships)
}
func Test_corruptPnpmLock(t *testing.T) {
pkgtest.NewCatalogTester().
FromFile(t, "test-fixtures/corrupt/pnpm-lock.yaml").
WithError().
TestParser(t, parsePnpmLock)
}
@@ -8,6 +8,7 @@ import (
"github.com/scylladb/go-set/strset"
"github.com/anchore/syft/internal/unknown"
"github.com/anchore/syft/syft/artifact"
"github.com/anchore/syft/syft/file"
"github.com/anchore/syft/syft/pkg"
@@ -112,7 +113,7 @@ func (a genericYarnLockAdapter) parseYarnLock(_ context.Context, resolver file.R
pkg.Sort(pkgs)
return pkgs, nil, nil
return pkgs, nil, unknown.IfEmptyf(pkgs, "unable to determine packages")
}
func findPackageName(line string) string {
@@ -0,0 +1,4 @@
{
"requires": true,
"lockfi
}
@@ -0,0 +1,5 @@
{
"version": "6.14.6",
"name"node": "6 >=6.2.0 || 8 || >=9.3.0"
}
}
@@ -0,0 +1,7 @@
lockfileVersion: 5.4
specifi
lution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==}
dev: true
# removed other packages