mirror of
https://github.com/anchore/syft.git
synced 2025-11-17 08:23:15 +01:00
Compare commits
2 Commits
a97e1c6e1a
...
725b0dfda2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
725b0dfda2 | ||
|
|
891499685a |
@ -135,10 +135,8 @@ graph LR
|
|||||||
style E2 fill:#fff9c4
|
style E2 fill:#fff9c4
|
||||||
```
|
```
|
||||||
|
|
||||||
### Key Data Flows
|
|
||||||
|
|
||||||
1. **Cataloger Discovery**: AST parser walks `syft/pkg/cataloger/` to find `generic.NewCataloger()` calls and extract parser information
|
1. **Cataloger Discovery**: AST parser walks `syft/pkg/cataloger/` to find `generic.NewCataloger()` calls and extract parser information
|
||||||
2. **Config Discovery**: AST parser finds config structs and extracts fields with `// app-config:` annotations
|
2. **Cataloger Config Discovery**: AST parser finds config structs and extracts fields with `// app-config:` annotations
|
||||||
3. **App Config Discovery**: AST parser extracts ecosystem configurations from options package, including descriptions and defaults
|
3. **App Config Discovery**: AST parser extracts ecosystem configurations from options package, including descriptions and defaults
|
||||||
4. **Metadata Discovery**: JSON reader loads test observations that record what metadata/package types each parser produces
|
4. **Metadata Discovery**: JSON reader loads test observations that record what metadata/package types each parser produces
|
||||||
5. **Linking**: AST analyzer connects catalogers to their config structs by examining constructor parameters
|
5. **Linking**: AST analyzer connects catalogers to their config structs by examining constructor parameters
|
||||||
|
|||||||
@ -478,18 +478,30 @@ func (e *EnrichmentData) EnrichWithBinaryClassifier(catalogerName string, entry
|
|||||||
// strip @version from PURL
|
// strip @version from PURL
|
||||||
purlStr := stripPURLVersion(classifier.PURL.String())
|
purlStr := stripPURLVersion(classifier.PURL.String())
|
||||||
|
|
||||||
|
packages := []capabilities.DetectorPackageInfo{
|
||||||
|
{
|
||||||
|
Class: classifier.Class,
|
||||||
|
Name: classifier.Package,
|
||||||
|
PURL: purlStr,
|
||||||
|
CPEs: cpeStrings,
|
||||||
|
Type: "BinaryPkg",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, o := range binaryClassifierOverrides[classifier.Class] {
|
||||||
|
packages = append(packages, capabilities.DetectorPackageInfo{
|
||||||
|
Class: o.Class,
|
||||||
|
Name: o.Package,
|
||||||
|
PURL: o.PURL,
|
||||||
|
CPEs: o.CPEs,
|
||||||
|
Type: "BinaryPkg",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
detectors = append(detectors, capabilities.Detector{
|
detectors = append(detectors, capabilities.Detector{
|
||||||
Method: "glob",
|
Method: "glob",
|
||||||
Criteria: []string{classifier.FileGlob},
|
Criteria: []string{classifier.FileGlob},
|
||||||
Packages: []capabilities.DetectorPackageInfo{
|
Packages: packages,
|
||||||
{
|
|
||||||
Class: classifier.Class,
|
|
||||||
Name: classifier.Package,
|
|
||||||
PURL: purlStr,
|
|
||||||
CPEs: cpeStrings,
|
|
||||||
Type: "BinaryPkg",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
entry.Detectors = detectors
|
entry.Detectors = detectors
|
||||||
|
|||||||
107
internal/capabilities/generate/overrides.go
Normal file
107
internal/capabilities/generate/overrides.go
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/anchore/syft/syft/cpe"
|
||||||
|
)
|
||||||
|
|
||||||
|
// this is a hack to get some information in the output that is otherwise difficult to extract.
|
||||||
|
// it should be removed after we figure out how to extract it properly from the classifiers
|
||||||
|
type binaryClassifierOverride struct {
|
||||||
|
Class string
|
||||||
|
Package string
|
||||||
|
PURL string
|
||||||
|
CPEs []string
|
||||||
|
}
|
||||||
|
|
||||||
|
var binaryClassifierOverrides = map[string][]binaryClassifierOverride{
|
||||||
|
"java-binary": {
|
||||||
|
{
|
||||||
|
Class: "java-binary-graalvm",
|
||||||
|
Package: "graalvm",
|
||||||
|
PURL: mustPURL("pkg:generic/oracle/graalvm@version"),
|
||||||
|
CPEs: singleCPE("cpe:2.3:a:oracle:graalvm:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Class: "java-binary-openjdk-zulu",
|
||||||
|
Package: "zulu",
|
||||||
|
PURL: mustPURL("pkg:generic/azul/zulu@version"),
|
||||||
|
CPEs: singleCPE("cpe:2.3:a:azul:zulu:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Class: "java-binary-openjdk-with-update",
|
||||||
|
Package: "openjdk",
|
||||||
|
PURL: mustPURL("pkg:generic/oracle/openjdk@version"),
|
||||||
|
CPEs: singleCPE("cpe:2.3:a:oracle:openjdk:{{.primary}}:update{{.update}}:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Class: "java-binary-openjdk",
|
||||||
|
Package: "openjdk",
|
||||||
|
PURL: mustPURL("pkg:generic/oracle/openjdk@version"),
|
||||||
|
CPEs: singleCPE("cpe:2.3:a:oracle:openjdk:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Class: "java-binary-ibm",
|
||||||
|
Package: "java",
|
||||||
|
PURL: mustPURL("pkg:generic/ibm/java@version"),
|
||||||
|
CPEs: singleCPE("cpe:2.3:a:ibm:java:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Class: "java-binary-openjdk-fallthrough",
|
||||||
|
Package: "jre",
|
||||||
|
PURL: mustPURL("pkg:generic/oracle/jre@version"),
|
||||||
|
CPEs: singleCPE("cpe:2.3:a:oracle:jre:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Class: "java-binary-oracle",
|
||||||
|
Package: "jre",
|
||||||
|
PURL: mustPURL("pkg:generic/oracle/jre@version"),
|
||||||
|
CPEs: singleCPE("cpe:2.3:a:oracle:jre:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"java-jdb-binary": {
|
||||||
|
{
|
||||||
|
Class: "java-binary-graalvm",
|
||||||
|
Package: "graalvm",
|
||||||
|
PURL: mustPURL("pkg:generic/oracle/graalvm@version"),
|
||||||
|
CPEs: singleCPE("cpe:2.3:a:oracle:graalvm_for_jdk:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Class: "jdb-binary-openjdk-zulu",
|
||||||
|
Package: "zulu",
|
||||||
|
PURL: mustPURL("pkg:generic/azul/zulu@version"),
|
||||||
|
CPEs: singleCPE("cpe:2.3:a:azul:zulu:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Class: "java-jdb-binary-openjdk",
|
||||||
|
Package: "openjdk",
|
||||||
|
PURL: mustPURL("pkg:generic/oracle/openjdk@version"),
|
||||||
|
CPEs: singleCPE("cpe:2.3:a:oracle:openjdk:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Class: "java-sdk-binary-ibm",
|
||||||
|
Package: "java_sdk",
|
||||||
|
PURL: mustPURL("pkg:generic/ibm/java_sdk@version"),
|
||||||
|
CPEs: singleCPE("cpe:2.3:a:ibm:java_sdk:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Class: "java-binary-openjdk-fallthrough",
|
||||||
|
Package: "openjdk",
|
||||||
|
PURL: mustPURL("pkg:generic/oracle/openjdk@version"),
|
||||||
|
CPEs: singleCPE("cpe:2.3:a:oracle:openjdk:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Class: "java-binary-jdk",
|
||||||
|
Package: "jdk",
|
||||||
|
PURL: mustPURL("pkg:generic/oracle/jdk@version"),
|
||||||
|
CPEs: singleCPE("cpe:2.3:a:oracle:jdk:*:*:*:*:*:*:*:*", cpe.NVDDictionaryLookupSource),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func mustPURL(purl string) string {
|
||||||
|
return purl
|
||||||
|
}
|
||||||
|
|
||||||
|
func singleCPE(cpeString string, _ ...any) []string {
|
||||||
|
return []string{cpeString}
|
||||||
|
}
|
||||||
@ -994,6 +994,48 @@ catalogers:
|
|||||||
purl: pkg:/
|
purl: pkg:/
|
||||||
cpes: []
|
cpes: []
|
||||||
type: BinaryPkg
|
type: BinaryPkg
|
||||||
|
- class: java-binary-graalvm
|
||||||
|
name: graalvm
|
||||||
|
purl: pkg:generic/oracle/graalvm@version
|
||||||
|
cpes:
|
||||||
|
- cpe:2.3:a:oracle:graalvm:*:*:*:*:*:*:*:*
|
||||||
|
type: BinaryPkg
|
||||||
|
- class: java-binary-openjdk-zulu
|
||||||
|
name: zulu
|
||||||
|
purl: pkg:generic/azul/zulu@version
|
||||||
|
cpes:
|
||||||
|
- cpe:2.3:a:azul:zulu:*:*:*:*:*:*:*:*
|
||||||
|
type: BinaryPkg
|
||||||
|
- class: java-binary-openjdk-with-update
|
||||||
|
name: openjdk
|
||||||
|
purl: pkg:generic/oracle/openjdk@version
|
||||||
|
cpes:
|
||||||
|
- cpe:2.3:a:oracle:openjdk:{{.primary}}:update{{.update}}:*:*:*:*:*:*
|
||||||
|
type: BinaryPkg
|
||||||
|
- class: java-binary-openjdk
|
||||||
|
name: openjdk
|
||||||
|
purl: pkg:generic/oracle/openjdk@version
|
||||||
|
cpes:
|
||||||
|
- cpe:2.3:a:oracle:openjdk:*:*:*:*:*:*:*:*
|
||||||
|
type: BinaryPkg
|
||||||
|
- class: java-binary-ibm
|
||||||
|
name: java
|
||||||
|
purl: pkg:generic/ibm/java@version
|
||||||
|
cpes:
|
||||||
|
- cpe:2.3:a:ibm:java:*:*:*:*:*:*:*:*
|
||||||
|
type: BinaryPkg
|
||||||
|
- class: java-binary-openjdk-fallthrough
|
||||||
|
name: jre
|
||||||
|
purl: pkg:generic/oracle/jre@version
|
||||||
|
cpes:
|
||||||
|
- cpe:2.3:a:oracle:jre:*:*:*:*:*:*:*:*
|
||||||
|
type: BinaryPkg
|
||||||
|
- class: java-binary-oracle
|
||||||
|
name: jre
|
||||||
|
purl: pkg:generic/oracle/jre@version
|
||||||
|
cpes:
|
||||||
|
- cpe:2.3:a:oracle:jre:*:*:*:*:*:*:*:*
|
||||||
|
type: BinaryPkg
|
||||||
- method: glob
|
- method: glob
|
||||||
criteria:
|
criteria:
|
||||||
- '**/jdb'
|
- '**/jdb'
|
||||||
@ -1003,6 +1045,42 @@ catalogers:
|
|||||||
purl: pkg:/
|
purl: pkg:/
|
||||||
cpes: []
|
cpes: []
|
||||||
type: BinaryPkg
|
type: BinaryPkg
|
||||||
|
- class: java-binary-graalvm
|
||||||
|
name: graalvm
|
||||||
|
purl: pkg:generic/oracle/graalvm@version
|
||||||
|
cpes:
|
||||||
|
- cpe:2.3:a:oracle:graalvm_for_jdk:*:*:*:*:*:*:*:*
|
||||||
|
type: BinaryPkg
|
||||||
|
- class: jdb-binary-openjdk-zulu
|
||||||
|
name: zulu
|
||||||
|
purl: pkg:generic/azul/zulu@version
|
||||||
|
cpes:
|
||||||
|
- cpe:2.3:a:azul:zulu:*:*:*:*:*:*:*:*
|
||||||
|
type: BinaryPkg
|
||||||
|
- class: java-jdb-binary-openjdk
|
||||||
|
name: openjdk
|
||||||
|
purl: pkg:generic/oracle/openjdk@version
|
||||||
|
cpes:
|
||||||
|
- cpe:2.3:a:oracle:openjdk:*:*:*:*:*:*:*:*
|
||||||
|
type: BinaryPkg
|
||||||
|
- class: java-sdk-binary-ibm
|
||||||
|
name: java_sdk
|
||||||
|
purl: pkg:generic/ibm/java_sdk@version
|
||||||
|
cpes:
|
||||||
|
- cpe:2.3:a:ibm:java_sdk:*:*:*:*:*:*:*:*
|
||||||
|
type: BinaryPkg
|
||||||
|
- class: java-binary-openjdk-fallthrough
|
||||||
|
name: openjdk
|
||||||
|
purl: pkg:generic/oracle/openjdk@version
|
||||||
|
cpes:
|
||||||
|
- cpe:2.3:a:oracle:openjdk:*:*:*:*:*:*:*:*
|
||||||
|
type: BinaryPkg
|
||||||
|
- class: java-binary-jdk
|
||||||
|
name: jdk
|
||||||
|
purl: pkg:generic/oracle/jdk@version
|
||||||
|
cpes:
|
||||||
|
- cpe:2.3:a:oracle:jdk:*:*:*:*:*:*:*:*
|
||||||
|
type: BinaryPkg
|
||||||
metadata_types: # AUTO-GENERATED
|
metadata_types: # AUTO-GENERATED
|
||||||
- pkg.BinarySignature
|
- pkg.BinarySignature
|
||||||
package_types: # AUTO-GENERATED
|
package_types: # AUTO-GENERATED
|
||||||
@ -3365,6 +3443,37 @@ catalogers:
|
|||||||
- package
|
- package
|
||||||
- python
|
- python
|
||||||
parsers: # AUTO-GENERATED structure
|
parsers: # AUTO-GENERATED structure
|
||||||
|
- function: parsePdmLock # AUTO-GENERATED
|
||||||
|
detector: # AUTO-GENERATED
|
||||||
|
method: glob # AUTO-GENERATED
|
||||||
|
criteria: # AUTO-GENERATED
|
||||||
|
- '**/pdm.lock'
|
||||||
|
metadata_types: # AUTO-GENERATED
|
||||||
|
- pkg.PythonPdmLockEntry
|
||||||
|
package_types: # AUTO-GENERATED
|
||||||
|
- python
|
||||||
|
json_schema_types: # AUTO-GENERATED
|
||||||
|
- PythonPdmLockEntry
|
||||||
|
capabilities: # MANUAL - config-driven capability definitions
|
||||||
|
- name: license
|
||||||
|
default: false
|
||||||
|
- name: dependency.depth
|
||||||
|
default:
|
||||||
|
- direct
|
||||||
|
- indirect
|
||||||
|
- name: dependency.edges
|
||||||
|
default: complete
|
||||||
|
- name: dependency.kinds
|
||||||
|
default:
|
||||||
|
- runtime
|
||||||
|
- dev
|
||||||
|
- optional
|
||||||
|
- name: package_manager.files.listing
|
||||||
|
default: false
|
||||||
|
- name: package_manager.files.digests
|
||||||
|
default: false
|
||||||
|
- name: package_manager.package_integrity_hash
|
||||||
|
default: false
|
||||||
- function: parseUvLock # AUTO-GENERATED
|
- function: parseUvLock # AUTO-GENERATED
|
||||||
detector: # AUTO-GENERATED
|
detector: # AUTO-GENERATED
|
||||||
method: glob # AUTO-GENERATED
|
method: glob # AUTO-GENERATED
|
||||||
@ -3387,6 +3496,7 @@ catalogers:
|
|||||||
default: complete
|
default: complete
|
||||||
- name: dependency.kinds
|
- name: dependency.kinds
|
||||||
default:
|
default:
|
||||||
|
- runtime
|
||||||
- dev
|
- dev
|
||||||
- optional
|
- optional
|
||||||
- name: package_manager.files.listing
|
- name: package_manager.files.listing
|
||||||
@ -3471,6 +3581,7 @@ catalogers:
|
|||||||
default: complete
|
default: complete
|
||||||
- name: dependency.kinds
|
- name: dependency.kinds
|
||||||
default:
|
default:
|
||||||
|
- runtime
|
||||||
- dev
|
- dev
|
||||||
- optional
|
- optional
|
||||||
- name: package_manager.files.listing
|
- name: package_manager.files.listing
|
||||||
@ -3478,8 +3589,10 @@ catalogers:
|
|||||||
- name: package_manager.files.digests
|
- name: package_manager.files.digests
|
||||||
default: false
|
default: false
|
||||||
- name: package_manager.package_integrity_hash
|
- name: package_manager.package_integrity_hash
|
||||||
default: false
|
default: true
|
||||||
- function: parseRequirementsTxt # AUTO-GENERATED
|
evidence:
|
||||||
|
- PythonPoetryLockEntry.PackageHashes
|
||||||
|
- function: parseRequirementsTxt
|
||||||
detector: # AUTO-GENERATED
|
detector: # AUTO-GENERATED
|
||||||
method: glob # AUTO-GENERATED
|
method: glob # AUTO-GENERATED
|
||||||
criteria: # AUTO-GENERATED
|
criteria: # AUTO-GENERATED
|
||||||
@ -3490,7 +3603,7 @@ catalogers:
|
|||||||
- python
|
- python
|
||||||
json_schema_types: # AUTO-GENERATED
|
json_schema_types: # AUTO-GENERATED
|
||||||
- PythonPipRequirementsEntry
|
- PythonPipRequirementsEntry
|
||||||
capabilities: # MANUAL - config-driven capability definitions
|
capabilities: # MANUAL - preserved across regeneration
|
||||||
- name: license
|
- name: license
|
||||||
default: false
|
default: false
|
||||||
- name: dependency.depth
|
- name: dependency.depth
|
||||||
|
|||||||
@ -14,7 +14,7 @@ import (
|
|||||||
"github.com/anchore/syft/syft/pkg/cataloger/internal/pkgtest"
|
"github.com/anchore/syft/syft/pkg/cataloger/internal/pkgtest"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_PackageCataloger(t *testing.T) {
|
func Test_InstalledPackageCataloger(t *testing.T) {
|
||||||
ctx := context.TODO()
|
ctx := context.TODO()
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
@ -402,10 +402,57 @@ func Test_PackageCataloger(t *testing.T) {
|
|||||||
|
|
||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
(pkgtest.NewCatalogTester().
|
pkgtest.NewCatalogTester().
|
||||||
FromDirectory(t, test.fixture).
|
FromDirectory(t, test.fixture).
|
||||||
Expects(test.expectedPackages, nil).
|
Expects(test.expectedPackages, nil).
|
||||||
TestCataloger(t, NewInstalledPackageCataloger()))
|
TestCataloger(t, NewInstalledPackageCataloger())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_PackageCataloger(t *testing.T) {
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
fixture string
|
||||||
|
expectedPackages []string
|
||||||
|
expectedRelationships []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "pdm",
|
||||||
|
fixture: "test-fixtures/pdm-lock",
|
||||||
|
expectedPackages: []string{
|
||||||
|
"certifi @ 2025.1.31 (pdm.lock)",
|
||||||
|
"chardet @ 3.0.4 (pdm.lock)",
|
||||||
|
"charset-normalizer @ 2.0.12 (pdm.lock)",
|
||||||
|
"colorama @ 0.3.9 (pdm.lock)",
|
||||||
|
"idna @ 2.7 (pdm.lock)",
|
||||||
|
"py @ 1.4.34 (pdm.lock)",
|
||||||
|
"pytest @ 3.2.5 (pdm.lock)",
|
||||||
|
"requests @ 2.27.1 (pdm.lock)",
|
||||||
|
"setuptools @ 39.2.0 (pdm.lock)",
|
||||||
|
"urllib3 @ 1.26.20 (pdm.lock)",
|
||||||
|
},
|
||||||
|
expectedRelationships: []string{
|
||||||
|
"certifi @ 2025.1.31 (pdm.lock) [dependency-of] requests @ 2.27.1 (pdm.lock)",
|
||||||
|
"chardet @ 3.0.4 (pdm.lock) [dependency-of] requests @ 2.27.1 (pdm.lock)",
|
||||||
|
"charset-normalizer @ 2.0.12 (pdm.lock) [dependency-of] requests @ 2.27.1 (pdm.lock)",
|
||||||
|
"colorama @ 0.3.9 (pdm.lock) [dependency-of] pytest @ 3.2.5 (pdm.lock)",
|
||||||
|
"idna @ 2.7 (pdm.lock) [dependency-of] requests @ 2.27.1 (pdm.lock)",
|
||||||
|
"py @ 1.4.34 (pdm.lock) [dependency-of] pytest @ 3.2.5 (pdm.lock)",
|
||||||
|
"setuptools @ 39.2.0 (pdm.lock) [dependency-of] pytest @ 3.2.5 (pdm.lock)",
|
||||||
|
"urllib3 @ 1.26.20 (pdm.lock) [dependency-of] requests @ 2.27.1 (pdm.lock)",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
pkgtest.NewCatalogTester().
|
||||||
|
FromDirectory(t, tt.fixture).
|
||||||
|
ExpectsPackageStrings(tt.expectedPackages).
|
||||||
|
ExpectsRelationshipStrings(tt.expectedRelationships).
|
||||||
|
TestCataloger(t, NewPackageCataloger(DefaultCatalogerConfig()))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user