diff --git a/go/purl/ecosystems_simple.go b/go/purl/ecosystems_simple.go index c2258a9f4b2..14225de31e3 100644 --- a/go/purl/ecosystems_simple.go +++ b/go/purl/ecosystems_simple.go @@ -67,7 +67,6 @@ func init() { registerSimple(osvconstants.EcosystemBitnami, "bitnami", "", nil) registerSimple(osvconstants.EcosystemCRAN, "cran", "", nil) registerSimple(osvconstants.EcosystemConanCenter, "conan", "", nil) - registerSimple(osvconstants.EcosystemDockerHardenedImages, "dhi", "", nil) registerSimple(osvconstants.EcosystemHackage, "hackage", "", nil) registerSlash(osvconstants.EcosystemHex, "hex") registerSimple(osvconstants.EcosystemJulia, "julia", "", nil) @@ -103,4 +102,14 @@ func init() { registerSimple(osvconstants.EcosystemAlpaquita, "apk", "alpaquita", sourceArchQualifiers) registerSimple(osvconstants.EcosystemAlpine, "apk", "alpine", sourceArchQualifiers) registerSimple(osvconstants.EcosystemBellSoftHardenedContainers, "apk", "bellsoft-hardened-containers", sourceArchQualifiers) + + // Docker Hardened Images + registerSimple(osvconstants.EcosystemDockerHardenedImages, "dhi", "", nil) + // DHI advisories also publish release-lineage PURLs -- pkg:apk/dhi/ + // for the Alpine lineage and pkg:deb/dhi/ for Debian -- so map both + // back to the ecosystem for PURL queries. Generation stays pkg:dhi/ (the + // registerSimple above); the dhi namespace disambiguates from Alpine + // (apk/alpine) and Debian (deb/debian), so there is no parser collision. + registerParser("apk", "dhi", simpleParser{ecosystem: osvconstants.EcosystemDockerHardenedImages}) + registerParser("deb", "dhi", simpleParser{ecosystem: osvconstants.EcosystemDockerHardenedImages}) } diff --git a/go/purl/purl_test.go b/go/purl/purl_test.go index f7f5d248a91..56aa73d3a51 100644 --- a/go/purl/purl_test.go +++ b/go/purl/purl_test.go @@ -25,6 +25,7 @@ func TestGenerate(t *testing.T) { {"npm", "@babel/core", "pkg:npm/%40babel/core", false}, {"Hex", "acme/foo", "pkg:hex/acme/foo", false}, {"SwiftURL", "github.com/apple/swift-markdown", "pkg:swift/github.com/apple/swift-markdown", false}, + {"Docker Hardened Images", "curl", "pkg:dhi/curl", false}, // Error cases {"UnknownEcosystem", "package", "", true}, } @@ -66,6 +67,13 @@ func TestParse(t *testing.T) { {"pkg:npm/%40babel/core@1.2.3", "npm", "@babel/core", "1.2.3", false}, {"pkg:hex/acme/foo@1.2.3", "Hex", "acme/foo", "1.2.3", false}, {"pkg:swift/github.com/apple/swift-markdown@1.2.3", "SwiftURL", "github.com/apple/swift-markdown", "1.2.3", false}, + // Docker Hardened Images: release-lineage PURLs resolve to the ecosystem. + // Qualifiers are ignored; versionless (OSV affected) and versioned (VEX + // product) forms both parse. pkg:dhi/ also still resolves. + {"pkg:apk/dhi/curl?os_distro=alpine&os_name=dhi&os_version=3.23", "Docker Hardened Images", "curl", "", false}, + {"pkg:apk/dhi/curl@8.4.0-r0", "Docker Hardened Images", "curl", "8.4.0-r0", false}, + {"pkg:deb/dhi/openssl@3.0.11-1", "Docker Hardened Images", "openssl", "3.0.11-1", false}, + {"pkg:dhi/curl@8.4.0-r0", "Docker Hardened Images", "curl", "8.4.0-r0", false}, // Error cases {"invalid-purl", "", "", "", true}, {"pkg:unknown/package@1.0.0", "", "", "", true},