github.com/lineaje-labs/syft@v0.98.1-0.20231227153149-9e393f60ff1b/syft/file/cataloger/filecontent/cataloger.go (about) 1 package filecontent 2 3 import ( 4 "bytes" 5 "encoding/base64" 6 "fmt" 7 "io" 8 9 "github.com/anchore/syft/syft/file" 10 "github.com/lineaje-labs/syft/internal" 11 "github.com/lineaje-labs/syft/internal/log" 12 ) 13 14 type Cataloger struct { 15 globs []string 16 skipFilesAboveSizeInBytes int64 17 } 18 19 func NewCataloger(globs []string, skipFilesAboveSize int64) (*Cataloger, error) { 20 return &Cataloger{ 21 globs: globs, 22 skipFilesAboveSizeInBytes: skipFilesAboveSize, 23 }, nil 24 } 25 26 func (i *Cataloger) Catalog(resolver file.Resolver) (map[file.Coordinates]string, error) { 27 results := make(map[file.Coordinates]string) 28 var locations []file.Location 29 30 locations, err := resolver.FilesByGlob(i.globs...) 31 if err != nil { 32 return nil, err 33 } 34 for _, location := range locations { 35 metadata, err := resolver.FileMetadataByLocation(location) 36 if err != nil { 37 return nil, err 38 } 39 40 if i.skipFilesAboveSizeInBytes > 0 && metadata.Size() > i.skipFilesAboveSizeInBytes { 41 continue 42 } 43 44 result, err := i.catalogLocation(resolver, location) 45 if internal.IsErrPathPermission(err) { 46 log.Debugf("file contents cataloger skipping - %+v", err) 47 continue 48 } 49 if err != nil { 50 return nil, err 51 } 52 results[location.Coordinates] = result 53 } 54 log.Debugf("file contents cataloger processed %d files", len(results)) 55 56 return results, nil 57 } 58 59 func (i *Cataloger) catalogLocation(resolver file.Resolver, location file.Location) (string, error) { 60 contentReader, err := resolver.FileContentsByLocation(location) 61 if err != nil { 62 return "", err 63 } 64 defer internal.CloseAndLogError(contentReader, location.AccessPath) 65 66 buf := &bytes.Buffer{} 67 encoder := base64.NewEncoder(base64.StdEncoding, buf) 68 if _, err = io.Copy(encoder, contentReader); err != nil { 69 return "", internal.ErrPath{Context: "contents-cataloger", Path: location.RealPath, Err: err} 70 } 71 // note: it's important to close the reader before reading from the buffer since closing will flush the remaining bytes 72 if err := encoder.Close(); err != nil { 73 return "", fmt.Errorf("unable to close base64 encoder: %w", err) 74 } 75 76 return buf.String(), nil 77 }