github.com/anchore/syft@v1.4.2-0.20240516191711-1bec1fc5d397/syft/pkg/cataloger/php/parse_pecl_serialized.go (about) 1 package php 2 3 import ( 4 "context" 5 "fmt" 6 "io" 7 8 "github.com/elliotchance/phpserialize" 9 10 "github.com/anchore/syft/internal/log" 11 "github.com/anchore/syft/syft/artifact" 12 "github.com/anchore/syft/syft/file" 13 "github.com/anchore/syft/syft/pkg" 14 "github.com/anchore/syft/syft/pkg/cataloger/generic" 15 ) 16 17 // parsePeclSerialized is a parser function for PECL metadata contents, returning "Default" php packages discovered. 18 func parsePeclSerialized(_ context.Context, _ file.Resolver, _ *generic.Environment, reader file.LocationReadCloser) ([]pkg.Package, []artifact.Relationship, error) { 19 var pkgs []pkg.Package 20 data, err := io.ReadAll(reader) 21 22 if err != nil { 23 return nil, nil, fmt.Errorf("failed to read file: %w", err) 24 } 25 26 metadata, err := phpserialize.UnmarshalAssociativeArray( 27 data, 28 ) 29 30 if err != nil { 31 return nil, nil, fmt.Errorf("failed to parse pecl metadata file: %w", err) 32 } 33 34 name, ok := metadata["name"].(string) 35 if !ok { 36 return nil, nil, fmt.Errorf("failed to parse pecl package name: %w", err) 37 } 38 39 version := readStruct(metadata, "version", "release") 40 license := readStruct(metadata, "license", "_content") 41 42 pkgs = append( 43 pkgs, 44 newPeclPackage( 45 pkg.PhpPeclEntry{ 46 Name: name, 47 Version: version, 48 License: []string{ 49 license, 50 }, 51 }, 52 reader.Location, 53 ), 54 ) 55 56 return pkgs, nil, nil 57 } 58 59 func readStruct(metadata any, fields ...string) string { 60 if len(fields) > 0 { 61 value, ok := metadata.(map[any]any) 62 if !ok { 63 log.Tracef("unable to read '%s' from: %v", fields[0], metadata) 64 return "" 65 } 66 return readStruct(value[fields[0]], fields[1:]...) 67 } 68 value, ok := metadata.(string) 69 if !ok { 70 log.Tracef("unable to read value from: %v", metadata) 71 } 72 return value 73 }