Skip to content

feat: CPEs format decoder#4207

Merged
kzantow merged 6 commits intoanchore:mainfrom
chovanecadam:cpe-list
Nov 12, 2025
Merged

feat: CPEs format decoder#4207
kzantow merged 6 commits intoanchore:mainfrom
chovanecadam:cpe-list

Conversation

@chovanecadam
Copy link
Copy Markdown
Contributor

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
Copy Markdown
Contributor 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
Copy Markdown
Contributor Author

Is there anything I can do to move this forward?

@kzantow
Copy link
Copy Markdown
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
Copy Markdown
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!

Comment thread syft/format/internal/backfill.go Outdated
backfillFromPurl(p)
}

if len(p.CPEs) != 0 {
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.

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

Copy link
Copy Markdown
Contributor 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
Copy Markdown
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
Copy Markdown
Contributor 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

Comment thread syft/format/cpes/decoder_test.go Outdated
}

syftPkgOpts := []cmp.Option{
cmpopts.IgnoreFields(pkg.Package{}, "id", "Type", "Language"),
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.

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

Copy link
Copy Markdown
Contributor 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 <git@adamchovanec.cz>
Signed-off-by: Adam Chovanec <git@adamchovanec.cz>
Signed-off-by: Adam Chovanec <git@adamchovanec.cz>
Signed-off-by: Adam Chovanec <git@adamchovanec.cz>
@chovanecadam
Copy link
Copy Markdown
Contributor Author

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

@chovanecadam chovanecadam requested a review from kzantow October 14, 2025 20:19
Comment thread syft/format/cpes/decoder_test.go
Comment thread syft/pkg/cataloger/common/cpe/target_software_to_pkg_type.go
Signed-off-by: Adam Chovanec <git@adamchovanec.cz>
to be used in Grype instead of its code

Signed-off-by: Adam Chovanec <git@adamchovanec.cz>
@chovanecadam
Copy link
Copy Markdown
Contributor 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.

Copy link
Copy Markdown
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.

Great! Thanks for the contribution @chovanecadam

@kzantow kzantow merged commit 102d362 into anchore:main Nov 12, 2025
12 checks passed
@chovanecadam chovanecadam deleted the cpe-list branch November 18, 2025 09:13
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