Skip to content

Conversation

@chovanecadam
Copy link

Description

Closes:

Adds a CPE decoder to aid Grype with scanning a file of CPEs. I have a WIP commit that implements that here: chovanecadam/grype@53bd626

This is my first bigger contribution to Syft, so please double-check if I didn't make some mistake.

I didn't implement an encoder. Syft generates many possible CPEs, I don't see a use-case for this output format.

Type of change

  • New feature (non-breaking change which adds functionality)

Checklist:

  • I have added unit tests that cover changed behavior
  • I have tested my code in common scenarios and confirmed there are no regressions

I have adopted the unit tests from grype/grype/pkg/cpe_provider_test.go as this basically implements the same functionality.

@chovanecadam chovanecadam changed the title feat: CPEs foramt decoder feat: CPEs format decoder Sep 10, 2025
@chovanecadam
Copy link
Author

Most of the code is adopted from decoder of package urls in syft and the tests are taken from Grype. I don't want to make it seem like I claim authorship of that.

@chovanecadam
Copy link
Author

Is there anything I can do to move this forward?

@kzantow
Copy link
Contributor

kzantow commented Sep 23, 2025

Thanks for the contribution @chovanecadam, sorry it got lost in the noise 🤦

For setting the package type from the CPE target_sw, I think we could move that to the Backfill process as the very last step if we could not determine package type otherwise. This would help to improve support for SBOMs with only CPEs and no other way to determine package type, too.

Also, would it be worthwhile adding a CPE output format? I'm inclined to say no, since it is such a lossy identifier compared to PURLs, which we do output. Leaving this input-only for now makes the most sense to me.

Copy link
Contributor

@kzantow kzantow left a comment

Choose a reason for hiding this comment

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

Sorry for the delay, just a couple of asks mostly related to testing; thanks very much for working on this @chovanecadam!

backfillFromPurl(p)
}

if len(p.CPEs) != 0 {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: is there a reason to have this check, since the backfillFromCPE is doing the same thing?

Copy link
Author

Choose a reason for hiding this comment

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

good nit, I removed superfluous tests in b3da15b


// CPETargetSoftwareToPackageType is derived from looking at target_software attributes in the NVD dataset
// TODO: ideally this would be driven from the store, where we can resolve ecosystem aliases directly
func CPETargetSoftwareToPackageType(tsw string) pkg.Type {
Copy link
Contributor

Choose a reason for hiding this comment

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

We should add some basic test for this function, probably in the decoder_test above -- I don't see any CPEs with targetSW set that result in execution of this logic, did I miss this or could you add a couple tests?

Copy link
Author

Choose a reason for hiding this comment

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

I added a few test cases to the cpe decoder_test as well as to the backfill_test

}

syftPkgOpts := []cmp.Option{
cmpopts.IgnoreFields(pkg.Package{}, "id", "Type", "Language"),
Copy link
Contributor

Choose a reason for hiding this comment

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

We probably want to actually test the Type here and add at least one test exercising multiple CPEs

Copy link
Author

Choose a reason for hiding this comment

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

Good point.

Adam Chovanec added 4 commits October 14, 2025 22:16
Signed-off-by: Adam Chovanec <[email protected]>
Signed-off-by: Adam Chovanec <[email protected]>
@chovanecadam
Copy link
Author

@kzantow I added test cases and rebased on top of main

@chovanecadam chovanecadam requested a review from kzantow October 14, 2025 20:19
"github.com/anchore/syft/syft/sbom"
)

func Test_CPEProvider(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

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

we should also test a list of cpes as well

Copy link
Author

Choose a reason for hiding this comment

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

thanks for the review, I added the tests

Copy link
Contributor

Choose a reason for hiding this comment

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

This was copied from grype/internal/cpe_target_software_to_pkg_type.go , which is ok, however, now we have two sources of truth for this kind of functionality. We should probably consider moving this to syft/pkg/cataloger/common/cpe/* expose this on the public API for grype to use.

Copy link
Author

@chovanecadam chovanecadam Nov 3, 2025

Choose a reason for hiding this comment

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

Implemented. The function is used in Grype in two places. If this mergerd we should open issue in Grype to make use of this function instead its own.

Signed-off-by: Adam Chovanec <[email protected]>
to be used in Grype instead of its code

Signed-off-by: Adam Chovanec <[email protected]>
@chovanecadam
Copy link
Author

Once this merges, I will create MR in Grype to make use of syft/pkg/cataloger/common/cpe/target_software_to_pkg_type.go instead its own and a separate MR that enables Grype to scan a list of CPEs.

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.

Support scanning a list of CPEs

3 participants