mirror of
https://github.com/anchore/syft.git
synced 2025-11-18 00:43:20 +01:00
npm: package-lock license decoding to accept string or array (#1482)
Signed-off-by: mikcl <mikesmikes400@gmail.com>
This commit is contained in:
parent
972e4cdaeb
commit
396441e921
@ -78,8 +78,8 @@ func newPackageLockV1Package(resolver source.FileResolver, location source.Locat
|
|||||||
func newPackageLockV2Package(resolver source.FileResolver, location source.Location, name string, u lockPackage) pkg.Package {
|
func newPackageLockV2Package(resolver source.FileResolver, location source.Location, name string, u lockPackage) pkg.Package {
|
||||||
var licenses []string
|
var licenses []string
|
||||||
|
|
||||||
if u.License != "" {
|
if u.License != nil {
|
||||||
licenses = append(licenses, u.License)
|
licenses = u.License
|
||||||
}
|
}
|
||||||
|
|
||||||
return finalizeLockPkg(
|
return finalizeLockPkg(
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/anchore/syft/internal/log"
|
||||||
"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/generic"
|
"github.com/anchore/syft/syft/pkg/cataloger/generic"
|
||||||
@ -24,6 +25,39 @@ type packageLock struct {
|
|||||||
Packages map[string]lockPackage
|
Packages map[string]lockPackage
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// packageLockLicense
|
||||||
|
type packageLockLicense []string
|
||||||
|
|
||||||
|
func (licenses *packageLockLicense) UnmarshalJSON(data []byte) (err error) {
|
||||||
|
// The license field could be either a string or an array.
|
||||||
|
|
||||||
|
// 1. An array
|
||||||
|
var arr []string
|
||||||
|
if err := json.Unmarshal(data, &arr); err == nil {
|
||||||
|
*licenses = arr
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. A string
|
||||||
|
var str string
|
||||||
|
if err = json.Unmarshal(data, &str); err == nil {
|
||||||
|
*licenses = make([]string, 1)
|
||||||
|
(*licenses)[0] = str
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// debug the content we did not expect
|
||||||
|
if len(data) > 0 {
|
||||||
|
log.WithFields("license", string(data)).Debug("Unable to parse the following `license` value in package-lock.json")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Unexpected
|
||||||
|
// In case we are unable to parse the license field,
|
||||||
|
// i.e if we have not covered the full specification,
|
||||||
|
// we do not want to throw an error, instead assign nil.
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// lockDependency represents a single package dependency listed in the package.lock json file
|
// lockDependency represents a single package dependency listed in the package.lock json file
|
||||||
type lockDependency struct {
|
type lockDependency struct {
|
||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
@ -36,7 +70,7 @@ type lockPackage struct {
|
|||||||
Version string `json:"version"`
|
Version string `json:"version"`
|
||||||
Resolved string `json:"resolved"`
|
Resolved string `json:"resolved"`
|
||||||
Integrity string `json:"integrity"`
|
Integrity string `json:"integrity"`
|
||||||
License string `json:"license"`
|
License packageLockLicense `json:"license"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// parsePackageLock parses a package-lock.json and returns the discovered JavaScript packages.
|
// parsePackageLock parses a package-lock.json and returns the discovered JavaScript packages.
|
||||||
|
|||||||
@ -297,3 +297,44 @@ func TestParsePackageLockAlias(t *testing.T) {
|
|||||||
pkgtest.TestFileParser(t, packageLock, parsePackageLock, expected, expectedRelationships)
|
pkgtest.TestFileParser(t, packageLock, parsePackageLock, expected, expectedRelationships)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestParsePackageLockLicenseWithArray(t *testing.T) {
|
||||||
|
fixture := "test-fixtures/pkg-lock/array-license-package-lock.json"
|
||||||
|
var expectedRelationships []artifact.Relationship
|
||||||
|
expectedPkgs := []pkg.Package{
|
||||||
|
{
|
||||||
|
Name: "tmp",
|
||||||
|
Version: "1.0.0",
|
||||||
|
Licenses: []string{"ISC"},
|
||||||
|
Language: pkg.JavaScript,
|
||||||
|
Type: pkg.NpmPkg,
|
||||||
|
PURL: "pkg:npm/tmp@1.0.0",
|
||||||
|
MetadataType: "NpmPackageLockJsonMetadata",
|
||||||
|
Metadata: pkg.NpmPackageLockJSONMetadata{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "pause-stream",
|
||||||
|
Version: "0.0.11",
|
||||||
|
Licenses: []string{"MIT", "Apache2"},
|
||||||
|
Language: pkg.JavaScript,
|
||||||
|
Type: pkg.NpmPkg,
|
||||||
|
PURL: "pkg:npm/pause-stream@0.0.11",
|
||||||
|
MetadataType: "NpmPackageLockJsonMetadata",
|
||||||
|
Metadata: pkg.NpmPackageLockJSONMetadata{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "through",
|
||||||
|
Version: "2.3.8",
|
||||||
|
Licenses: []string{"MIT"},
|
||||||
|
Language: pkg.JavaScript,
|
||||||
|
Type: pkg.NpmPkg,
|
||||||
|
PURL: "pkg:npm/through@2.3.8",
|
||||||
|
MetadataType: "NpmPackageLockJsonMetadata",
|
||||||
|
Metadata: pkg.NpmPackageLockJSONMetadata{},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for i := range expectedPkgs {
|
||||||
|
expectedPkgs[i].Locations.Add(source.NewLocation(fixture))
|
||||||
|
}
|
||||||
|
pkgtest.TestFileParser(t, fixture, parsePackageLock, expectedPkgs, expectedRelationships)
|
||||||
|
}
|
||||||
|
|||||||
41
syft/pkg/cataloger/javascript/test-fixtures/pkg-lock/array-license-package-lock.json
generated
Normal file
41
syft/pkg/cataloger/javascript/test-fixtures/pkg-lock/array-license-package-lock.json
generated
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"name": "tmp",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"lockfileVersion": 2,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"name": "tmp",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"pause-stream": "0.0.11"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/pause-stream": {
|
||||||
|
"version": "0.0.11",
|
||||||
|
"license": [
|
||||||
|
"MIT",
|
||||||
|
"Apache2"
|
||||||
|
],
|
||||||
|
"dependencies": {
|
||||||
|
"through": "~2.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/through": {
|
||||||
|
"version": "2.3.8",
|
||||||
|
"license": "MIT"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"pause-stream": {
|
||||||
|
"version": "0.0.11",
|
||||||
|
"requires": {
|
||||||
|
"through": "~2.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"through": {
|
||||||
|
"version": "2.3.8"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user