github.com/anchore/syft@v1.38.2/syft/pkg/cataloger/internal/binutils/classifier_package.go (about) 1 package binutils 2 3 import ( 4 "bytes" 5 "reflect" 6 "text/template" 7 8 "github.com/anchore/packageurl-go" 9 "github.com/anchore/syft/internal/log" 10 "github.com/anchore/syft/syft/cpe" 11 "github.com/anchore/syft/syft/file" 12 "github.com/anchore/syft/syft/pkg" 13 ) 14 15 var emptyPURL = packageurl.PackageURL{} 16 17 func NewClassifierPackage(classifier Classifier, location file.Location, matchMetadata map[string]string, catalogerName string) *pkg.Package { 18 version, ok := matchMetadata["version"] 19 if !ok { 20 return nil 21 } 22 23 update := matchMetadata["update"] 24 25 var cpes []cpe.CPE 26 for _, c := range classifier.CPEs { 27 c.Attributes.Version = templatedUpdate(c.Attributes.Version, matchMetadata, version) 28 c.Attributes.Update = templatedUpdate(c.Attributes.Update, matchMetadata, update) 29 cpes = append(cpes, c) 30 } 31 32 p := pkg.Package{ 33 Name: classifier.Package, 34 Version: version, 35 Locations: file.NewLocationSet( 36 location.WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation), 37 ), 38 Type: pkg.BinaryPkg, 39 CPEs: cpes, 40 FoundBy: catalogerName, 41 Metadata: pkg.BinarySignature{ 42 Matches: []pkg.ClassifierMatch{ 43 { 44 Classifier: classifier.Class, 45 Location: location, 46 }, 47 }, 48 }, 49 } 50 51 if !reflect.DeepEqual(classifier.PURL, emptyPURL) { 52 purl := classifier.PURL 53 purl.Version = version 54 p.PURL = purl.ToString() 55 } 56 57 p.SetID() 58 59 return &p 60 } 61 62 func templatedUpdate(providedValue string, matchMetadata map[string]string, defaultValue string) string { 63 // if no template provided, just use the value directly 64 if providedValue == "" { 65 return defaultValue 66 } 67 // support templated updates 68 t, err := template.New("").Option("missingkey=zero").Parse(providedValue) 69 if err != nil { 70 log.Debugf("unable to parse classifier template=%q : %w", providedValue, err) 71 } else { 72 update := bytes.Buffer{} 73 err = t.Execute(&update, matchMetadata) 74 if err != nil { 75 log.Debugf("unable to render template: %w", err) 76 } else { 77 // only use the template result if it's non-empty 78 providedValue = update.String() 79 if providedValue != "" { 80 return providedValue 81 } 82 } 83 } 84 return defaultValue 85 }