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  }