Projects STRLCPY syft Commits 7714bc05
🤬
Revision indexing in progress... (symbol navigation in revisions will be accurate after indexed)
  • ■ ■ ■ ■ ■ ■
    .github/workflows/validations.yaml
    skipped 53 lines
    54 54   path: syft/pkg/cataloger/golang/test-fixtures/archs/binaries
    55 55   key: ${{ runner.os }}-unit-go-binaries-cache-${{ hashFiles( 'syft/pkg/cataloger/golang/test-fixtures/archs/binaries.fingerprint' ) }}
    56 56   
     57 + - name: Restore binary cataloger test-fixture cache
     58 + id: unit-binary-cataloger-cache
     59 + uses: actions/cache@v3
     60 + with:
     61 + path: syft/pkg/cataloger/binary/test-fixtures/classifiers/dynamic
     62 + key: ${{ runner.os }}-unit-binary-cataloger-cache-${{ hashFiles( 'syft/pkg/cataloger/binary/test-fixtures/cache.fingerprint' ) }}
     63 + 
    57 64   - name: Run unit tests
    58 65   run: make unit
    59 66   
    skipped 143 lines
  • ■ ■ ■ ■ ■
    Makefile
    skipped 188 lines
    189 189   cd test/integration/test-fixtures && \
    190 190   make cache.fingerprint
    191 191   
     192 + # for BINARY test fixtures
     193 + cd syft/pkg/cataloger/binary/test-fixtures && \
     194 + make cache.fingerprint
     195 + 
    192 196   # for JAVA BUILD test fixtures
    193 197   cd syft/pkg/cataloger/java/test-fixtures/java-builds && \
    194 198   make packages.fingerprint
    skipped 19 lines
    214 218   $(call title,Generating test fixtures)
    215 219   cd syft/pkg/cataloger/java/test-fixtures/java-builds && make
    216 220   cd syft/pkg/cataloger/rpm/test-fixtures && make
     221 + cd syft/pkg/cataloger/binary/test-fixtures && make
    217 222   
    218 223  .PHONY: show-test-image-cache
    219 224  show-test-image-cache: ## Show all docker and image tar cache
    skipped 159 lines
  • ■ ■ ■ ■ ■
    syft/pkg/cataloger/binary/cataloger.go
    skipped 73 lines
    74 74   return nil, err
    75 75   }
    76 76   for _, location := range locations {
    77  - reader, err := resolver.FileContentsByLocation(location)
    78  - if err != nil {
    79  - return nil, err
    80  - }
    81  - locationReader := source.NewLocationReadCloser(location, reader)
    82  - pkgs, err := cls.EvidenceMatcher(cls, locationReader)
     77 + pkgs, err := cls.EvidenceMatcher(resolver, cls, location)
    83 78   if err != nil {
    84 79   return nil, err
    85 80   }
    skipped 17 lines
  • ■ ■ ■ ■ ■ ■
    syft/pkg/cataloger/binary/cataloger_test.go
    skipped 3 lines
    4 4   "errors"
    5 5   "fmt"
    6 6   "io"
     7 + "strings"
    7 8   "testing"
    8 9   
     10 + "github.com/google/go-cmp/cmp"
     11 + "github.com/google/go-cmp/cmp/cmpopts"
    9 12   "github.com/stretchr/testify/assert"
    10 13   "github.com/stretchr/testify/require"
    11 14   
    skipped 54 lines
    66 69   PURL: "pkg:generic/[email protected]",
    67 70   Locations: locations("postgres"),
    68 71   Metadata: metadata("postgresql-binary"),
    69  - },
    70  - },
    71  - {
    72  - name: "positive-python-duplicates",
    73  - fixtureDir: "test-fixtures/classifiers/positive/python-duplicates",
    74  - expected: pkg.Package{
    75  - Name: "python",
    76  - Version: "3.8.16",
    77  - Type: "binary",
    78  - PURL: "pkg:generic/[email protected]",
    79  - Locations: locations("dir/python3.8", "python3.8", "libpython3.8.so", "patchlevel.h"),
    80  - Metadata: pkg.BinaryMetadata{
    81  - Matches: []pkg.ClassifierMatch{
    82  - match("python-binary", "dir/python3.8"),
    83  - match("python-binary", "python3.8"),
    84  - match("python-binary-lib", "libpython3.8.so"),
    85  - match("cpython-source", "patchlevel.h"),
    86  - },
    87  - },
    88 72   },
    89 73   },
    90 74   {
    skipped 224 lines
    315 299   },
    316 300   },
    317 301   {
     302 + name: "positive-python-3.11.2-from-shared-lib",
     303 + fixtureDir: "test-fixtures/classifiers/dynamic/python-binary-shared-lib-3.11",
     304 + expected: pkg.Package{
     305 + Name: "python",
     306 + Version: "3.11.2",
     307 + PURL: "pkg:generic/[email protected]",
     308 + Locations: locations("python3", "libpython3.11.so.1.0"),
     309 + Metadata: pkg.BinaryMetadata{
     310 + Matches: []pkg.ClassifierMatch{
     311 + match("python-binary", "python3"),
     312 + match("python-binary", "libpython3.11.so.1.0"),
     313 + match("python-binary-lib", "libpython3.11.so.1.0"),
     314 + },
     315 + },
     316 + },
     317 + },
     318 + {
     319 + name: "positive-python-3.9-from-shared-redhat-lib",
     320 + fixtureDir: "test-fixtures/classifiers/dynamic/python-binary-shared-lib-redhat-3.9",
     321 + expected: pkg.Package{
     322 + Name: "python",
     323 + Version: "3.9.13",
     324 + PURL: "pkg:generic/[email protected]",
     325 + Locations: locations("python3.9", "libpython3.9.so.1.0"),
     326 + Metadata: pkg.BinaryMetadata{
     327 + Matches: []pkg.ClassifierMatch{
     328 + match("python-binary", "python3.9"),
     329 + match("python-binary", "libpython3.9.so.1.0"),
     330 + match("python-binary-lib", "libpython3.9.so.1.0"),
     331 + },
     332 + },
     333 + },
     334 + },
     335 + {
     336 + name: "positive-python-binary-with-version-3.9",
     337 + fixtureDir: "test-fixtures/classifiers/dynamic/python-binary-with-version-3.9",
     338 + expected: pkg.Package{
     339 + Name: "python",
     340 + Version: "3.9.2",
     341 + PURL: "pkg:generic/[email protected]",
     342 + Locations: locations("python3.9"),
     343 + Metadata: pkg.BinaryMetadata{
     344 + Matches: []pkg.ClassifierMatch{
     345 + match("python-binary", "python3.9"),
     346 + },
     347 + },
     348 + },
     349 + },
     350 + {
    318 351   name: "positive-python3.6",
    319 352   fixtureDir: "test-fixtures/classifiers/positive/python-binary-3.6",
    320 353   expected: pkg.Package{
    321 354   Name: "python",
    322  - Version: "3.6.3a-vZ9",
    323  - PURL: "pkg:generic/[email protected].3a-vZ9",
     355 + Version: "3.6.3",
     356 + PURL: "pkg:generic/[email protected].3",
    324 357   Locations: locations("python3.6"),
    325 358   Metadata: metadata("python-binary"),
    326 359   },
    327 360   },
    328 361   {
    329  - name: "positive-patchlevel.h",
    330  - fixtureDir: "test-fixtures/classifiers/positive/python-source-3.9",
     362 + name: "positive-python-duplicates",
     363 + fixtureDir: "test-fixtures/classifiers/positive/python-duplicates",
    331 364   expected: pkg.Package{
    332 365   Name: "python",
    333  - Version: "3.9-aZ5",
    334  - PURL: "pkg:generic/[email protected]",
    335  - Locations: locations("patchlevel.h"),
    336  - Metadata: metadata("cpython-source"),
     366 + Version: "3.8.16",
     367 + Type: "binary",
     368 + PURL: "pkg:generic/[email protected]",
     369 + Locations: locations("dir/python3.8", "python3.8", "libpython3.8.so"),
     370 + Metadata: pkg.BinaryMetadata{
     371 + Matches: []pkg.ClassifierMatch{
     372 + match("python-binary", "dir/python3.8"),
     373 + match("python-binary", "python3.8"),
     374 + match("python-binary-lib", "libpython3.8.so"),
     375 + },
     376 + },
    337 377   },
    338 378   },
    339 379   {
    skipped 151 lines
    491 531   require.NoError(t, err)
    492 532   
    493 533   for _, p := range packages {
    494  - expectedLocations := test.expected.Locations.ToSlice()
    495  - gotLocations := p.Locations.ToSlice()
    496  - require.Len(t, gotLocations, len(expectedLocations))
    497  - 
    498  - for i, expectedLocation := range expectedLocations {
    499  - gotLocation := gotLocations[i]
    500  - if expectedLocation.RealPath != gotLocation.RealPath {
    501  - t.Fatalf("locations do not match; expected: %v got: %v", expectedLocations, gotLocations)
    502  - }
    503  - }
    504  - 
    505 534   assertPackagesAreEqual(t, test.expected, p)
    506 535   }
    507 536   })
    skipped 103 lines
    611 640  }
    612 641   
    613 642  func assertPackagesAreEqual(t *testing.T, expected pkg.Package, p pkg.Package) {
     643 + var failMessages []string
     644 + expectedLocations := expected.Locations.ToSlice()
     645 + gotLocations := p.Locations.ToSlice()
     646 + 
     647 + if len(expectedLocations) != len(gotLocations) {
     648 + failMessages = append(failMessages, "locations are not equal length")
     649 + } else {
     650 + for i, expectedLocation := range expectedLocations {
     651 + gotLocation := gotLocations[i]
     652 + if expectedLocation.RealPath != gotLocation.RealPath {
     653 + failMessages = append(failMessages, fmt.Sprintf("locations do not match; expected: %v got: %v", expectedLocation.RealPath, gotLocation.RealPath))
     654 + }
     655 + }
     656 + }
     657 + 
    614 658   m1 := expected.Metadata.(pkg.BinaryMetadata).Matches
    615 659   m2 := p.Metadata.(pkg.BinaryMetadata).Matches
    616 660   matches := true
    skipped 16 lines
    633 677   } else {
    634 678   matches = false
    635 679   }
     680 + 
     681 + if !matches {
     682 + failMessages = append(failMessages, "classifier matches not equal")
     683 + }
    636 684   if expected.Name != p.Name ||
    637 685   expected.Version != p.Version ||
    638  - expected.PURL != p.PURL ||
    639  - !matches {
    640  - assert.Failf(t, "packages not equal", "%v != %v", stringifyPkg(expected), stringifyPkg(p))
     686 + expected.PURL != p.PURL {
     687 + failMessages = append(failMessages, "packages do not match")
    641 688   }
    642  -}
    643 689   
    644  -func stringifyPkg(p pkg.Package) string {
    645  - matches := p.Metadata.(pkg.BinaryMetadata).Matches
    646  - return fmt.Sprintf("(name=%s, version=%s, purl=%s, matches=%+v)", p.Name, p.Version, p.PURL, matches)
     690 + if len(failMessages) > 0 {
     691 + assert.Failf(t, strings.Join(failMessages, "; "), "diff: %s",
     692 + cmp.Diff(expected, p,
     693 + cmp.Transformer("Locations", func(l source.LocationSet) []source.Location {
     694 + return l.ToSlice()
     695 + }),
     696 + cmpopts.IgnoreUnexported(pkg.Package{}, source.Location{}),
     697 + cmpopts.IgnoreFields(pkg.Package{}, "CPEs", "FoundBy", "MetadataType", "Type"),
     698 + ))
     699 + }
    647 700  }
    648 701   
    649 702  type panicyResolver struct {
    skipped 65 lines
  • ■ ■ ■ ■ ■
    syft/pkg/cataloger/binary/classifier.go
    skipped 1 lines
    2 2   
    3 3  import (
    4 4   "bytes"
     5 + "debug/elf"
     6 + "debug/macho"
     7 + "debug/pe"
    5 8   "fmt"
    6 9   "io"
    7 10   "reflect"
    skipped 2 lines
    10 13   
    11 14   "github.com/anchore/packageurl-go"
    12 15   "github.com/anchore/syft/internal"
     16 + "github.com/anchore/syft/internal/log"
    13 17   "github.com/anchore/syft/syft/cpe"
    14 18   "github.com/anchore/syft/syft/pkg"
    15 19   "github.com/anchore/syft/syft/pkg/cataloger/internal/unionreader"
    skipped 33 lines
    49 53  }
    50 54   
    51 55  // evidenceMatcher is a function called to catalog Packages that match some sort of evidence
    52  -type evidenceMatcher func(classifier classifier, reader source.LocationReadCloser) ([]pkg.Package, error)
     56 +type evidenceMatcher func(resolver source.FileResolver, classifier classifier, location source.Location) ([]pkg.Package, error)
    53 57   
    54 58  func evidenceMatchers(matchers ...evidenceMatcher) evidenceMatcher {
    55  - return func(classifier classifier, reader source.LocationReadCloser) ([]pkg.Package, error) {
     59 + return func(resolver source.FileResolver, classifier classifier, location source.Location) ([]pkg.Package, error) {
    56 60   for _, matcher := range matchers {
    57  - match, err := matcher(classifier, reader)
     61 + match, err := matcher(resolver, classifier, location)
    58 62   if err != nil {
    59 63   return nil, err
    60 64   }
    skipped 7 lines
    68 72   
    69 73  func fileNameTemplateVersionMatcher(fileNamePattern string, contentTemplate string) evidenceMatcher {
    70 74   pat := regexp.MustCompile(fileNamePattern)
    71  - return func(classifier classifier, reader source.LocationReadCloser) ([]pkg.Package, error) {
    72  - if !pat.MatchString(reader.RealPath) {
     75 + return func(resolver source.FileResolver, classifier classifier, location source.Location) ([]pkg.Package, error) {
     76 + if !pat.MatchString(location.RealPath) {
    73 77   return nil, nil
    74 78   }
    75 79   
    76  - filepathNamedGroupValues := internal.MatchNamedCaptureGroups(pat, reader.RealPath)
     80 + filepathNamedGroupValues := internal.MatchNamedCaptureGroups(pat, location.RealPath)
    77 81   
    78 82   tmpl, err := template.New("").Parse(contentTemplate)
    79 83   if err != nil {
    skipped 11 lines
    91 95   return nil, fmt.Errorf("unable to compile rendered regex=%q: %w", patternBuf.String(), err)
    92 96   }
    93 97   
    94  - contents, err := getContents(reader)
     98 + contents, err := getContents(resolver, location)
    95 99   if err != nil {
    96 100   return nil, fmt.Errorf("unable to get read contents for file: %w", err)
    97 101   }
    98 102   
    99 103   matchMetadata := internal.MatchNamedCaptureGroups(tmplPattern, string(contents))
    100  - return singlePackage(classifier, reader, matchMetadata), nil
     104 + return singlePackage(classifier, location, matchMetadata), nil
    101 105   }
    102 106  }
    103 107   
    104 108  func fileContentsVersionMatcher(pattern string) evidenceMatcher {
    105 109   pat := regexp.MustCompile(pattern)
    106  - return func(classifier classifier, reader source.LocationReadCloser) ([]pkg.Package, error) {
    107  - contents, err := getContents(reader)
     110 + return func(resolver source.FileResolver, classifier classifier, location source.Location) ([]pkg.Package, error) {
     111 + contents, err := getContents(resolver, location)
    108 112   if err != nil {
    109 113   return nil, fmt.Errorf("unable to get read contents for file: %w", err)
    110 114   }
    111 115   
    112 116   matchMetadata := internal.MatchNamedCaptureGroups(pat, string(contents))
    113  - return singlePackage(classifier, reader, matchMetadata), nil
     117 + return singlePackage(classifier, location, matchMetadata), nil
     118 + }
     119 +}
     120 + 
     121 +//nolint:gocognit
     122 +func sharedLibraryLookup(sharedLibraryPattern string, sharedLibraryMatcher evidenceMatcher) evidenceMatcher {
     123 + pat := regexp.MustCompile(sharedLibraryPattern)
     124 + return func(resolver source.FileResolver, classifier classifier, location source.Location) (packages []pkg.Package, _ error) {
     125 + libs, err := sharedLibraries(resolver, location)
     126 + if err != nil {
     127 + return nil, err
     128 + }
     129 + for _, lib := range libs {
     130 + if !pat.MatchString(lib) {
     131 + continue
     132 + }
     133 + 
     134 + locations, err := resolver.FilesByGlob("**/" + lib)
     135 + if err != nil {
     136 + return nil, err
     137 + }
     138 + for _, libraryLication := range locations {
     139 + pkgs, err := sharedLibraryMatcher(resolver, classifier, libraryLication)
     140 + if err != nil {
     141 + return nil, err
     142 + }
     143 + for _, p := range pkgs {
     144 + // set the source binary as the first location
     145 + locationSet := source.NewLocationSet(location)
     146 + locationSet.Add(p.Locations.ToSlice()...)
     147 + p.Locations = locationSet
     148 + meta, _ := p.Metadata.(pkg.BinaryMetadata)
     149 + p.Metadata = pkg.BinaryMetadata{
     150 + Matches: append([]pkg.ClassifierMatch{
     151 + {
     152 + Classifier: classifier.Class,
     153 + Location: location,
     154 + },
     155 + }, meta.Matches...),
     156 + }
     157 + packages = append(packages, p)
     158 + }
     159 + }
     160 + }
     161 + return packages, nil
    114 162   }
    115 163  }
    116 164   
    skipped 5 lines
    122 170   return p
    123 171  }
    124 172   
    125  -func singlePackage(classifier classifier, reader source.LocationReadCloser, matchMetadata map[string]string) []pkg.Package {
     173 +func singlePackage(classifier classifier, location source.Location, matchMetadata map[string]string) []pkg.Package {
    126 174   version, ok := matchMetadata["version"]
    127 175   if !ok {
    128 176   return nil
    skipped 11 lines
    140 188   p := pkg.Package{
    141 189   Name: classifier.Package,
    142 190   Version: version,
    143  - Locations: source.NewLocationSet(reader.Location),
     191 + Locations: source.NewLocationSet(location),
    144 192   Type: pkg.BinaryPkg,
    145 193   CPEs: cpes,
    146 194   FoundBy: catalogerName,
    skipped 2 lines
    149 197   Matches: []pkg.ClassifierMatch{
    150 198   {
    151 199   Classifier: classifier.Class,
    152  - Location: reader.Location,
     200 + Location: location,
    153 201   },
    154 202   },
    155 203   },
    skipped 18 lines
    174 222   return []pkg.Package{p}
    175 223  }
    176 224   
    177  -func getContents(reader source.LocationReadCloser) ([]byte, error) {
    178  - unionReader, err := unionreader.GetUnionReader(reader.ReadCloser)
     225 +func getContents(resolver source.FileResolver, location source.Location) ([]byte, error) {
     226 + reader, err := resolver.FileContentsByLocation(location)
     227 + if err != nil {
     228 + return nil, err
     229 + }
     230 + 
     231 + unionReader, err := unionreader.GetUnionReader(reader)
    179 232   if err != nil {
    180 233   return nil, fmt.Errorf("unable to get union reader for file: %w", err)
    181 234   }
    skipped 14 lines
    196 249   }
    197 250  }
    198 251   
     252 +// sharedLibraries returns a list of all shared libraries found within a binary, currently
     253 +// supporting: elf, macho, and windows pe
     254 +func sharedLibraries(resolver source.FileResolver, location source.Location) ([]string, error) {
     255 + contents, err := getContents(resolver, location)
     256 + if err != nil {
     257 + return nil, err
     258 + }
     259 + 
     260 + r := bytes.NewReader(contents)
     261 + 
     262 + e, _ := elf.NewFile(r)
     263 + if e != nil {
     264 + symbols, err := e.ImportedLibraries()
     265 + if err != nil {
     266 + log.Debugf("unable to read elf binary at: %s -- %s", location.RealPath, err)
     267 + }
     268 + return symbols, nil
     269 + }
     270 + 
     271 + m, _ := macho.NewFile(r)
     272 + if m != nil {
     273 + symbols, err := m.ImportedLibraries()
     274 + if err != nil {
     275 + log.Debugf("unable to read macho binary at: %s -- %s", location.RealPath, err)
     276 + }
     277 + return symbols, nil
     278 + }
     279 + 
     280 + p, _ := pe.NewFile(r)
     281 + if p != nil {
     282 + symbols, err := p.ImportedLibraries()
     283 + if err != nil {
     284 + log.Debugf("unable to read pe binary at: %s -- %s", location.RealPath, err)
     285 + }
     286 + return symbols, nil
     287 + }
     288 + 
     289 + return nil, nil
     290 +}
     291 + 
  • ■ ■ ■ ■ ■ ■
    syft/pkg/cataloger/binary/classifier_test.go
    skipped 66 lines
    67 67   locations, err := resolver.FilesByPath(test.fixture)
    68 68   require.NoError(t, err)
    69 69   require.Len(t, locations, 1)
    70  - location := locations[0]
    71  - readCloser, err := resolver.FileContentsByLocation(location)
    72  - require.NoError(t, err)
    73  - pkgs, err := test.classifier.EvidenceMatcher(test.classifier, source.NewLocationReadCloser(location, readCloser))
     70 + 
     71 + pkgs, err := test.classifier.EvidenceMatcher(resolver, test.classifier, locations[0])
    74 72   require.NoError(t, err)
    75 73   
    76 74   require.Len(t, pkgs, 1)
    skipped 12 lines
  • ■ ■ ■ ■ ■ ■
    syft/pkg/cataloger/binary/default_classifiers.go
    skipped 8 lines
    9 9   {
    10 10   Class: "python-binary",
    11 11   FileGlob: "**/python*",
    12  - EvidenceMatcher: fileNameTemplateVersionMatcher(
    13  - `(.*/|^)python(?P<version>[0-9]+\.[0-9]+)$`,
    14  - `(?m)(?P<version>{{ .version }}\.[0-9]+[-_a-zA-Z0-9]*)`),
     12 + EvidenceMatcher: evidenceMatchers(
     13 + // try to find version information from libpython shared libraries
     14 + sharedLibraryLookup(
     15 + `^libpython[0-9]+(?:\.[0-9]+)+\.so.*$`,
     16 + libpythonMatcher),
     17 + // check for version information in the binary
     18 + fileNameTemplateVersionMatcher(
     19 + `(?:.*/|^)python(?P<version>[0-9]+(?:\.[0-9]+)+)$`,
     20 + pythonVersionTemplate),
     21 + ),
    15 22   Package: "python",
    16 23   PURL: mustPURL("pkg:generic/python@version"),
    17 24   CPEs: []cpe.CPE{
    skipped 2 lines
    20 27   },
    21 28   },
    22 29   {
    23  - Class: "python-binary-lib",
    24  - FileGlob: "**/libpython*.so*",
    25  - EvidenceMatcher: fileNameTemplateVersionMatcher(
    26  - `(.*/|^)libpython(?P<version>[0-9]+\.[0-9]+).so.*$`,
    27  - `(?m)(?P<version>{{ .version }}\.[0-9]+[-_a-zA-Z0-9]*)`),
    28  - Package: "python",
    29  - PURL: mustPURL("pkg:generic/python@version"),
    30  - CPEs: []cpe.CPE{
    31  - cpe.Must("cpe:2.3:a:python_software_foundation:python:*:*:*:*:*:*:*:*"),
    32  - cpe.Must("cpe:2.3:a:python:python:*:*:*:*:*:*:*:*"),
    33  - },
    34  - },
    35  - {
    36  - Class: "cpython-source",
    37  - FileGlob: "**/patchlevel.h",
    38  - EvidenceMatcher: fileContentsVersionMatcher(
    39  - `(?m)#define\s+PY_VERSION\s+"?(?P<version>[0-9\.\-_a-zA-Z]+)"?`),
    40  - Package: "python",
    41  - PURL: mustPURL("pkg:generic/python@version"),
     30 + Class: "python-binary-lib",
     31 + FileGlob: "**/libpython*.so*",
     32 + EvidenceMatcher: libpythonMatcher,
     33 + Package: "python",
     34 + PURL: mustPURL("pkg:generic/python@version"),
    42 35   CPEs: []cpe.CPE{
    43 36   cpe.Must("cpe:2.3:a:python_software_foundation:python:*:*:*:*:*:*:*:*"),
    44 37   cpe.Must("cpe:2.3:a:python:python:*:*:*:*:*:*:*:*"),
    skipped 184 lines
    229 222   },
    230 223  }
    231 224   
     225 +// in both binaries and shared libraries, the version pattern is [NUL]3.11.2[NUL]
     226 +var pythonVersionTemplate = `(?m)\x00(?P<version>{{ .version }}[-._a-zA-Z0-9]*)\x00`
     227 + 
     228 +var libpythonMatcher = fileNameTemplateVersionMatcher(
     229 + `(?:.*/|^)libpython(?P<version>[0-9]+(?:\.[0-9]+)+)\.so.*$`,
     230 + pythonVersionTemplate,
     231 +)
     232 + 
  • ■ ■ ■ ■ ■ ■
    syft/pkg/cataloger/binary/test-fixtures/.gitignore
     1 +classifiers/dynamic
     2 + 
  • ■ ■ ■ ■ ■ ■
    syft/pkg/cataloger/binary/test-fixtures/Makefile
     1 +.PHONY: all
     2 +all: \
     3 + classifiers/dynamic/python-binary-shared-lib-3.11 \
     4 + classifiers/dynamic/python-binary-shared-lib-redhat-3.9 \
     5 + classifiers/dynamic/python-binary-with-version-3.9
     6 + 
     7 +classifiers/dynamic/python-binary-shared-lib-3.11:
     8 + $(eval $@_image := "python:3.11-slim@sha256:0b106e1d2bf485c2a41474bc9cd5103e9eea4e179f40f10741b53b127059221e")
     9 + ./get-image-file.sh $($@_image) \
     10 + /usr/local/bin/python3.11 \
     11 + $@/python3
     12 + ./get-image-file.sh $($@_image) \
     13 + /usr/local/lib/libpython3.11.so.1.0 \
     14 + $@/libpython3.11.so.1.0
     15 + 
     16 +classifiers/dynamic/python-binary-shared-lib-redhat-3.9:
     17 + $(eval $@_image := "registry.access.redhat.com/ubi8/python-39@sha256:f3cf958b96ce016b63e3e163e488f52e42891304dafef5a0811563f22e3cbad0")
     18 + ./get-image-file.sh $($@_image) \
     19 + /usr/bin/python3.9 \
     20 + $@/python3.9
     21 + ./get-image-file.sh $($@_image) \
     22 + /usr/lib64/libpython3.9.so.1.0 \
     23 + $@/libpython3.9.so.1.0
     24 + 
     25 +classifiers/dynamic/python-binary-with-version-3.9:
     26 + $(eval $@_image := "python:3.9.16-bullseye@sha256:93fb93c461a2e47a2176706fad1f39eaacd5dd40e19c0b018699a28c03eb2e2a")
     27 + ./get-image-file.sh $($@_image) \
     28 + /usr/bin/python3.9 \
     29 + $@/python3.9
     30 + 
     31 +.PHONY: clean
     32 +clean:
     33 + rm -rf classifiers/dynamic
     34 + 
     35 +.PHONY: cache.fingerprint
     36 +cache.fingerprint: # for CI
     37 + $(title,Install test fixture fingerprint)
     38 + @find ./classifiers/dynamic/* -type f -exec md5sum {} + | awk '{print $1}' | sort | tee /dev/stderr | md5sum | tee cache.fingerprint >> cache.fingerprint
     39 + 
  • syft/pkg/cataloger/binary/test-fixtures/classifiers/positive/python-binary-3.6/python3.6
    Binary file.
  • syft/pkg/cataloger/binary/test-fixtures/classifiers/positive/python-duplicates/dir/python3.8
    Binary file.
  • syft/pkg/cataloger/binary/test-fixtures/classifiers/positive/python-duplicates/libpython3.8.so
    Binary file.
  • syft/pkg/cataloger/binary/test-fixtures/classifiers/positive/python-duplicates/python3.8
    Binary file.
  • ■ ■ ■ ■ ■ ■
    syft/pkg/cataloger/binary/test-fixtures/classifiers/positive/python-source-3.9/patchlevel.h
    1  -# note: this SHOULD match as python 3.9
    2  - 
    3  -some source code...
    4  - 
    5  -#define PY_VERSION 3.9-aZ5
    6  - 
    7  -more source!
  • ■ ■ ■ ■ ■ ■
    syft/pkg/cataloger/binary/test-fixtures/get-image-file.sh
     1 +#!/usr/bin/env bash
     2 +set -uxe
     3 + 
     4 +CTRID=$(docker create $1)
     5 + 
     6 +function cleanup() {
     7 + docker rm "${CTRID}"
     8 +}
     9 + 
     10 +trap cleanup EXIT
     11 +set +e
     12 + 
     13 +mkdir -p $(dirname $3)
     14 + 
     15 +docker cp ${CTRID}:$2 $3
     16 + 
Please wait...
Page is in error, reload to recover