github.com/noqcks/syft@v0.0.0-20230920222752-a9e2c4e288e5/syft/pkg/cataloger/php/parse_installed_json.go (about) 1 package php 2 3 import ( 4 "encoding/json" 5 "errors" 6 "fmt" 7 "io" 8 9 "github.com/anchore/syft/syft/artifact" 10 "github.com/anchore/syft/syft/file" 11 "github.com/anchore/syft/syft/pkg" 12 "github.com/anchore/syft/syft/pkg/cataloger/generic" 13 ) 14 15 var _ generic.Parser = parseComposerLock 16 17 // Note: composer version 2 introduced a new structure for the installed.json file, so we support both 18 type installedJSONComposerV2 struct { 19 Packages []parsedData `json:"packages"` 20 } 21 22 func (w *installedJSONComposerV2) UnmarshalJSON(data []byte) error { 23 type compv2 struct { 24 Packages []parsedData `json:"packages"` 25 } 26 compv2er := new(compv2) 27 err := json.Unmarshal(data, &compv2er) 28 if err != nil { 29 // If we had an err or, we may be dealing with a composer v.1 installed.json 30 // which should be all arrays 31 var packages []parsedData 32 err := json.Unmarshal(data, &packages) 33 if err != nil { 34 return err 35 } 36 w.Packages = packages 37 return nil 38 } 39 w.Packages = compv2er.Packages 40 return nil 41 } 42 43 // parseInstalledJSON is a parser function for Composer.lock contents, returning "Default" php packages discovered. 44 func parseInstalledJSON(_ file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) { 45 var pkgs []pkg.Package 46 dec := json.NewDecoder(reader) 47 48 for { 49 var lock installedJSONComposerV2 50 if err := dec.Decode(&lock); errors.Is(err, io.EOF) { 51 break 52 } else if err != nil { 53 return nil, nil, fmt.Errorf("failed to parse installed.json file: %w", err) 54 } 55 for _, pkgMeta := range lock.Packages { 56 pkgs = append( 57 pkgs, 58 newComposerLockPackage(pkgMeta, 59 reader.Location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), 60 ), 61 ) 62 } 63 } 64 65 return pkgs, nil, nil 66 }