Compare commits

...

2 Commits

Author SHA1 Message Date
Keith Zantow
725b0dfda2
chore: java binary data
Signed-off-by: Keith Zantow <kzantow@gmail.com>
2025-11-14 15:44:38 -05:00
Alex Goodman
891499685a fix pdm
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
2025-11-07 15:42:46 -05:00
5 changed files with 295 additions and 18 deletions

View File

@ -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

View File

@ -478,10 +478,7 @@ 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())
detectors = append(detectors, capabilities.Detector{ packages := []capabilities.DetectorPackageInfo{
Method: "glob",
Criteria: []string{classifier.FileGlob},
Packages: []capabilities.DetectorPackageInfo{
{ {
Class: classifier.Class, Class: classifier.Class,
Name: classifier.Package, Name: classifier.Package,
@ -489,7 +486,22 @@ func (e *EnrichmentData) EnrichWithBinaryClassifier(catalogerName string, entry
CPEs: cpeStrings, CPEs: cpeStrings,
Type: "BinaryPkg", 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{
Method: "glob",
Criteria: []string{classifier.FileGlob},
Packages: packages,
}) })
} }
entry.Detectors = detectors entry.Detectors = detectors

View 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}
}

View File

@ -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

View File

@ -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()))
}) })
} }
} }