diff --git a/syft/cataloger/javascript/parse_package_json.go b/syft/cataloger/javascript/parse_package_json.go index 654f1b68b..244cb8585 100644 --- a/syft/cataloger/javascript/parse_package_json.go +++ b/syft/cataloger/javascript/parse_package_json.go @@ -2,6 +2,7 @@ package javascript import ( "encoding/json" + "errors" "fmt" "io" "regexp" @@ -22,7 +23,7 @@ type PackageJSON struct { Version string `json:"version"` Latest []string `json:"latest"` Author Author `json:"author"` - License string `json:"license"` + License json.RawMessage `json:"license"` Name string `json:"name"` Homepage string `json:"homepage"` Description string `json:"description"` @@ -107,6 +108,29 @@ func (r *Repository) UnmarshalJSON(b []byte) error { return nil } +type license struct { + Type string `json:"type"` + URL string `json:"url"` +} + +func licenseFromJSON(b []byte) (string, error) { + // first try as string + var licenseString string + err := json.Unmarshal(b, &licenseString) + if err == nil { + return licenseString, nil + } + + // then try as object (this format is deprecated) + var licenseObject license + err = json.Unmarshal(b, &licenseObject) + if err == nil { + return licenseObject.Type, nil + } + + return "", errors.New("unable to unmarshal license field as either string or object") +} + // parsePackageJson parses a package.json and returns the discovered JavaScript packages. func parsePackageJSON(_ string, reader io.Reader) ([]pkg.Package, error) { packages := make([]pkg.Package, 0) @@ -120,10 +144,16 @@ func parsePackageJSON(_ string, reader io.Reader) ([]pkg.Package, error) { return nil, fmt.Errorf("failed to parse package.json file: %w", err) } + singleLicense, err := licenseFromJSON(p.License) + if err != nil { + return nil, fmt.Errorf("failed to parse package.json file: %w", err) + } + licenses := []string{singleLicense} + packages = append(packages, pkg.Package{ Name: p.Name, Version: p.Version, - Licenses: []string{p.License}, + Licenses: licenses, Language: pkg.JavaScript, Type: pkg.NpmPkg, MetadataType: pkg.NpmPackageJSONMetadataType, @@ -131,7 +161,7 @@ func parsePackageJSON(_ string, reader io.Reader) ([]pkg.Package, error) { Author: p.Author.AuthorString(), Homepage: p.Homepage, URL: p.Repository.URL, - Licenses: []string{p.License}, + Licenses: licenses, }, }) }