github.com/anchore/syft@v1.38.2/syft/pkg/cataloger/binary/elf_package.go (about)

     1  package binary
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/anchore/packageurl-go"
     7  	"github.com/anchore/syft/internal/log"
     8  	"github.com/anchore/syft/syft/cpe"
     9  	"github.com/anchore/syft/syft/file"
    10  	"github.com/anchore/syft/syft/pkg"
    11  )
    12  
    13  func newELFPackage(ctx context.Context, metadata elfBinaryPackageNotes, locations file.LocationSet) pkg.Package {
    14  	p := pkg.Package{
    15  		Name:      metadata.Name,
    16  		Version:   metadata.Version,
    17  		Licenses:  pkg.NewLicenseSet(pkg.NewLicenseWithContext(ctx, metadata.License)),
    18  		PURL:      elfPackageURL(metadata),
    19  		Type:      pkgType(metadata.Type),
    20  		Locations: locations,
    21  		Metadata:  metadata.ELFBinaryPackageNoteJSONPayload,
    22  	}
    23  
    24  	p.SetID()
    25  
    26  	return p
    27  }
    28  
    29  func elfPackageURL(metadata elfBinaryPackageNotes) string {
    30  	var qualifiers []packageurl.Qualifier
    31  
    32  	os, osVersion := osNameAndVersionFromMetadata(metadata)
    33  
    34  	if os != "" {
    35  		osQualifier := os
    36  		if osVersion != "" {
    37  			osQualifier += "-" + osVersion
    38  		}
    39  		qualifiers = append(qualifiers, packageurl.Qualifier{
    40  			Key:   "distro",
    41  			Value: osQualifier,
    42  		})
    43  	}
    44  
    45  	ty := purlDistroType(metadata.Type)
    46  
    47  	namespace := os
    48  
    49  	if ty == packageurl.TypeGeneric || os == "" {
    50  		namespace = metadata.System
    51  	}
    52  
    53  	return packageurl.NewPackageURL(
    54  		ty,
    55  		namespace,
    56  		metadata.Name,
    57  		metadata.Version,
    58  		qualifiers,
    59  		"",
    60  	).ToString()
    61  }
    62  
    63  func osNameAndVersionFromMetadata(metadata elfBinaryPackageNotes) (string, string) {
    64  	os := metadata.OS
    65  	osVersion := metadata.OSVersion
    66  
    67  	if os != "" && osVersion != "" {
    68  		return os, osVersion
    69  	}
    70  
    71  	if metadata.OSCPE == "" {
    72  		return "", ""
    73  	}
    74  
    75  	attrs, err := cpe.NewAttributes(metadata.OSCPE)
    76  	if err != nil {
    77  		log.WithFields("error", err).Trace("unable to parse cpe attributes for elf binary package")
    78  		return "", ""
    79  	}
    80  	return attrs.Product, attrs.Version
    81  }
    82  
    83  const alpmType = "alpm"
    84  
    85  func purlDistroType(ty string) string {
    86  	switch ty {
    87  	case "rpm":
    88  		return packageurl.TypeRPM
    89  	case "deb":
    90  		return packageurl.TypeDebian
    91  	case "apk":
    92  		return packageurl.TypeAlpine
    93  	case alpmType:
    94  		return alpmType
    95  	}
    96  	return packageurl.TypeGeneric
    97  }
    98  
    99  func pkgType(ty string) pkg.Type {
   100  	switch ty {
   101  	case "rpm":
   102  		return pkg.RpmPkg
   103  	case "deb":
   104  		return pkg.DebPkg
   105  	case "apk":
   106  		return pkg.ApkPkg
   107  	case alpmType:
   108  		return pkg.AlpmPkg
   109  	}
   110  	return pkg.BinaryPkg
   111  }