github.com/lineaje-labs/syft@v0.98.1-0.20231227153149-9e393f60ff1b/syft/pkg/cataloger/rust/parse_audit_binary.go (about)

     1  package rust
     2  
     3  import (
     4  	"errors"
     5  
     6  	rustaudit "github.com/microsoft/go-rustaudit"
     7  
     8  	"github.com/anchore/syft/syft/artifact"
     9  	"github.com/anchore/syft/syft/file"
    10  	"github.com/anchore/syft/syft/pkg"
    11  	"github.com/anchore/syft/syft/pkg/cataloger/generic"
    12  	"github.com/lineaje-labs/syft/internal/log"
    13  	"github.com/lineaje-labs/syft/syft/pkg/cataloger/internal/unionreader"
    14  )
    15  
    16  // Catalog identifies executables then attempts to read Rust dependency information from them
    17  func parseAuditBinary(
    18  	_ file.Resolver, _ *generic.Environment, reader file.LocationReadCloser,
    19  ) ([]pkg.Package, []artifact.Relationship, error) {
    20  	var pkgs []pkg.Package
    21  
    22  	unionReader, err := unionreader.GetUnionReader(reader.ReadCloser)
    23  	if err != nil {
    24  		return nil, nil, err
    25  	}
    26  
    27  	for _, versionInfo := range parseAuditBinaryEntry(unionReader, reader.RealPath) {
    28  		pkgs = append(pkgs, newPackagesFromAudit(reader.Location, versionInfo)...)
    29  	}
    30  
    31  	return pkgs, nil, nil
    32  }
    33  
    34  // scanFile scans file to try to report the Rust crate dependencies
    35  func parseAuditBinaryEntry(reader unionreader.UnionReader, filename string) []rustaudit.VersionInfo {
    36  	// NOTE: multiple readers are returned to cover universal binaries, which are files
    37  	// with more than one binary
    38  	readers, err := unionreader.GetReaders(reader)
    39  	if err != nil {
    40  		log.Warnf("rust cataloger: failed to open a binary: %v", err)
    41  		return nil
    42  	}
    43  
    44  	var versionInfos []rustaudit.VersionInfo
    45  	for _, r := range readers {
    46  		versionInfo, err := rustaudit.GetDependencyInfo(r)
    47  
    48  		if err != nil {
    49  			if errors.Is(err, rustaudit.ErrNoRustDepInfo) {
    50  				// since the cataloger can only select executables and not distinguish if they are a Rust-compiled
    51  				// binary, we should not show warnings/logs in this case.
    52  				return nil
    53  			}
    54  			log.Tracef("rust cataloger: unable to read dependency information (file=%q): %v", filename, err)
    55  			return nil
    56  		}
    57  
    58  		versionInfos = append(versionInfos, versionInfo)
    59  	}
    60  
    61  	return versionInfos
    62  }