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