Skip to content

fix: use full namespaced name for db search PURLs#3531

Open
arpitjain099 wants to merge 1 commit into
anchore:mainfrom
arpitjain099:chore/db-search-purl-module-path
Open

fix: use full namespaced name for db search PURLs#3531
arpitjain099 wants to merge 1 commit into
anchore:mainfrom
arpitjain099:chore/db-search-purl-module-path

Conversation

@arpitjain099

Copy link
Copy Markdown

Fixes #3508.

grype db search --pkg with a golang PURL doesn't match because the package specifier is built from purl.Name only. For ecosystems that carry part of the name in the PURL namespace, that drops the rest of the name. So pkg:golang/github.com/gin-gonic/gin gets searched as just gin, and nothing matches (the DB keys the record under the full module path github.com/gin-gonic/gin).

This adds an ecosystem-aware packageNameFromPURL in PostLoad that reconstructs the stored name:

  • golang and npm join namespace/name (e.g. github.com/gin-gonic/gin, @babel/core)
  • Maven joins groupId:artifactId
  • everything else keeps purl.Name (unchanged behavior for flat-namespaced ecosystems)

It's the same reconstruction the openvex build transformer already does (grype/db/v6/build/transformers/openvex), so the search side and the data side now agree on the name. I extended it to cover golang since that's what the issue hit.

Testing

Added table cases to TestDBSearchPackagesPostLoad for the golang module path, npm scope, and Maven group:artifact mappings (the plain-name fallback was already covered).

$ go test ./cmd/grype/cli/options/...
ok      github.com/anchore/grype/cmd/grype/cli/options

// Without this, a search for a namespaced PURL only used purl.Name and silently
// failed to match. This mirrors the same reconstruction the openvex build
// transformer performs (grype/db/v6/build/transformers/openvex).
func packageNameFromPURL(purl *packageurl.PackageURL) string {

@kzantow kzantow Jul 3, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @arpitjain099 -- we talked about this on the livestream and the consensus is we should handle PURLs the same as when scanning here. There are a number of other nuances that occur when you run grype against a PURL compared to when you specify a PURL here. The simple solution would be to use the SBOM decoder to get a package, which will have all the information from the PURL as we expect it in a package. After that, we probably want to use the PackageNames function to get all the search names for a given package. This will result in correctly searching for NPM, Java, Golang, and other packages and avoid these functions drifting

@kzantow kzantow left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per the comment we should convert PURLs to packages and use the PackageNames function to search the same way matching will

grype db search --pkg built the package specifier straight from the
raw PURL fields, using only purl.Name. For ecosystems that carry part
of the name in the PURL namespace this dropped the rest of the name, so
the search never matched. A golang module PURL like
pkg:golang/github.com/gin-gonic/gin was searched as just "gin" instead
of github.com/gin-gonic/gin.

Decode the PURL into a package through the same provider path used when
scanning, then ask the DB name resolver (name.PackageNames) for the
search names. This reconstructs golang module paths, npm scopes, and
Maven group:artifact coordinates, and also applies ecosystem-specific
normalization such as PEP 503 for Python, without this command
reimplementing any of it. The ecosystem is taken from the decoded syft
package type, which the search layer already normalizes.

Fixes anchore#3508

Signed-off-by: Arpit Jain <arpitjain099@gmail.com>
@arpitjain099 arpitjain099 force-pushed the chore/db-search-purl-module-path branch from ea373b3 to 9a7efc5 Compare July 3, 2026 15:22
@arpitjain099

Copy link
Copy Markdown
Author

Thanks @kzantow, that makes a lot of sense. I reworked it to go through the same path as scanning: decode the PURL into a package via pkg.Provide, then feed each package to name.PackageNames to get the search names, and build the specifiers from those. So Golang module paths, npm scopes, and Maven group:artifact now resolve the way they do during a scan, and Python even picks up PEP 503 normalization for free. The custom per-ecosystem helper is gone. Updated the tests to cover those cases (build/vet/tests pass locally).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

grype db search does not properly parse golang PURL

2 participants