github.com/anchore/syft@v1.4.2-0.20240516191711-1bec1fc5d397/syft/pkg/cataloger/redhat/dependency.go (about)

     1  package redhat
     2  
     3  import (
     4  	"strings"
     5  
     6  	"github.com/anchore/syft/internal/log"
     7  	"github.com/anchore/syft/syft/pkg"
     8  	"github.com/anchore/syft/syft/pkg/cataloger/internal/dependency"
     9  )
    10  
    11  var _ dependency.Specifier = dbEntryDependencySpecifier
    12  
    13  func dbEntryDependencySpecifier(p pkg.Package) dependency.Specification {
    14  	meta, ok := p.Metadata.(pkg.RpmDBEntry)
    15  	if !ok {
    16  		log.Tracef("cataloger failed to extract rpmdb metadata for package %+v", p.Name)
    17  		return dependency.Specification{}
    18  	}
    19  
    20  	provides := []string{p.Name}
    21  	for _, key := range meta.Provides {
    22  		if key == "" {
    23  			continue
    24  		}
    25  		if !isSupportedKey(key) {
    26  			continue
    27  		}
    28  		provides = append(provides, key)
    29  	}
    30  
    31  	// all owned files are also considered "provides" for the package
    32  	for _, f := range meta.Files {
    33  		provides = append(provides, f.Path)
    34  	}
    35  
    36  	var requires []string
    37  	for _, key := range meta.Requires {
    38  		if key == "" {
    39  			continue
    40  		}
    41  		if !isSupportedKey(key) {
    42  			continue
    43  		}
    44  		requires = append(requires, key)
    45  	}
    46  
    47  	return dependency.Specification{
    48  		Provides: provides,
    49  		Requires: requires,
    50  	}
    51  }
    52  
    53  func isSupportedKey(key string) bool {
    54  	// '(' indicates the start of a boolean expression, which is not supported in syft at this time.
    55  	// See https://rpm-software-management.github.io/rpm/manual/boolean_dependencies.html for more details
    56  	//
    57  	// examples:
    58  	//  - (rpmlib(PayloadIsZstd) <= 5.4.18-1)
    59  	//  - (glibc-gconv-extra(aarch-64) = 2.34-83.el9.12 if redhat-rpm-config)
    60  	//  - (java-headless or java-17-headless or java-11-headless or java-1.8.0-headless)
    61  	//  - (llvm if clang)
    62  	//  - (pyproject-rpm-macros = 1.9.0-1.el9 if pyproject-rpm-macros)
    63  	//  - (gcc >= 11 with gcc < 12)
    64  
    65  	return !strings.HasPrefix(strings.TrimSpace(key), "(")
    66  }