fix(cpe): fix generated cpe for rust packages

---------
Signed-off-by: Xenira <1288524+Xenira@users.noreply.github.com>
This commit is contained in:
Xenira 2026-08-20 21:01:24 +02:00 committed by GitHub
parent fd4796b0d8
commit 490732aa58
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 69 additions and 36 deletions

View File

@ -184,9 +184,13 @@ func FromPackageAttributes(p pkg.Package) []cpe.CPE {
} }
func candidateTargetSw(p pkg.Package) []string { func candidateTargetSw(p pkg.Package) []string {
if p.Type == pkg.WordpressPluginPkg { switch p.Type {
case pkg.WordpressPluginPkg:
return []string{"wordpress"} return []string{"wordpress"}
case pkg.RustPkg:
return []string{"rust"}
} }
return []string{cpe.Any} return []string{cpe.Any}
} }
@ -217,6 +221,50 @@ func candidateVendors(p pkg.Package) []string {
} }
} }
vendors = candidateVendorsByType(p, vendors)
if p.Type == pkg.BinaryPkg && endsWithNumber(p.Name) {
// add binary package digit-suffix variations (e.g. Qt5 -> Qt)
addBinaryPackageDigitVariations(vendors)
}
// We should no longer be generating vendor candidates with these values ["" and "*"]
// (since CPEs will match any other value)
vendors.removeByValue("")
vendors.removeByValue("*")
// try swapping hyphens for underscores, vice versa, and removing separators altogether
addDelimiterVariations(vendors)
// rust vendor name needs to be added after the `addDelimiterVariations` call as `-project` suffix is used otherwise
if p.Language == pkg.Rust {
vendors.addValue(p.Name + "_project")
}
// generate sub-selections of each candidate based on separators (e.g. jenkins-ci -> [jenkins, jenkins-ci])
addAllSubSelections(vendors)
// add more candidates based on the package info for each vendor candidate
for _, vendor := range vendors.uniqueValues() {
vendors.addValue(findAdditionalVendors(defaultCandidateAdditions, p.Type, p.Name, vendor)...)
}
// remove known mis
vendors.removeByValue(findVendorsToRemove(defaultCandidateRemovals, p.Type, p.Name)...)
uniqueVendors := vendors.uniqueValues()
// if any known vendor was detected, pick that one.
for _, vendor := range uniqueVendors {
if knownVendors.Has(vendor) {
return []string{vendor}
}
}
return uniqueVendors
}
func candidateVendorsByType(p pkg.Package, vendors fieldCandidateSet) fieldCandidateSet {
switch p.Metadata.(type) { switch p.Metadata.(type) {
case pkg.DotnetDepsEntry, pkg.DotnetPackagesLockEntry, pkg.DotnetPortableExecutableEntry: case pkg.DotnetDepsEntry, pkg.DotnetPackagesLockEntry, pkg.DotnetPortableExecutableEntry:
vendors.clear() vendors.clear()
@ -240,41 +288,7 @@ func candidateVendors(p pkg.Package) []string {
vendors.clear() vendors.clear()
vendors.union(candidateVendorsForWordpressPlugin(p)) vendors.union(candidateVendorsForWordpressPlugin(p))
} }
return vendors
if p.Type == pkg.BinaryPkg && endsWithNumber(p.Name) {
// add binary package digit-suffix variations (e.g. Qt5 -> Qt)
addBinaryPackageDigitVariations(vendors)
}
// We should no longer be generating vendor candidates with these values ["" and "*"]
// (since CPEs will match any other value)
vendors.removeByValue("")
vendors.removeByValue("*")
// try swapping hyphens for underscores, vice versa, and removing separators altogether
addDelimiterVariations(vendors)
// generate sub-selections of each candidate based on separators (e.g. jenkins-ci -> [jenkins, jenkins-ci])
addAllSubSelections(vendors)
// add more candidates based on the package info for each vendor candidate
for _, vendor := range vendors.uniqueValues() {
vendors.addValue(findAdditionalVendors(defaultCandidateAdditions, p.Type, p.Name, vendor)...)
}
// remove known mis
vendors.removeByValue(findVendorsToRemove(defaultCandidateRemovals, p.Type, p.Name)...)
uniqueVendors := vendors.uniqueValues()
// if any known vendor was detected, pick that one.
for _, vendor := range uniqueVendors {
if knownVendors.Has(vendor) {
return []string{vendor}
}
}
return uniqueVendors
} }
func candidateProducts(p pkg.Package) []string { func candidateProducts(p pkg.Package) []string {

View File

@ -855,6 +855,25 @@ func TestGeneratePackageCPEs(t *testing.T) {
}, },
expected: []string{}, expected: []string{},
}, },
{
name: "rust package",
p: pkg.Package{
Name: "rust-package",
Version: "0.5.0",
Type: pkg.RustPkg,
Language: pkg.Rust,
},
expected: []string{
"cpe:2.3:a:rust-package_project:rust-package:0.5.0:*:*:*:*:rust:*:*",
"cpe:2.3:a:rust-package_project:rust_package:0.5.0:*:*:*:*:rust:*:*",
"cpe:2.3:a:rust-package:rust-package:0.5.0:*:*:*:*:rust:*:*",
"cpe:2.3:a:rust-package:rust_package:0.5.0:*:*:*:*:rust:*:*",
"cpe:2.3:a:rust:rust-package:0.5.0:*:*:*:*:rust:*:*",
"cpe:2.3:a:rust:rust_package:0.5.0:*:*:*:*:rust:*:*",
"cpe:2.3:a:rust_package:rust-package:0.5.0:*:*:*:*:rust:*:*",
"cpe:2.3:a:rust_package:rust_package:0.5.0:*:*:*:*:rust:*:*",
},
},
} }
for _, test := range tests { for _, test := range tests {