Skip to content

fix: skip SBOM components with UNKNOWN version instead of raising exception#5646

Open
nancysangani wants to merge 2 commits intoossf:mainfrom
nancysangani:fix/unknown-version-sbom-exception
Open

fix: skip SBOM components with UNKNOWN version instead of raising exception#5646
nancysangani wants to merge 2 commits intoossf:mainfrom
nancysangani:fix/unknown-version-sbom-exception

Conversation

@nancysangani
Copy link
Copy Markdown

Fixes #5302

When scanning a CycloneDX SBOM containing a component with version "UNKNOWN",
cve_scanner.py raised an unhandled UnknownVersion exception that terminated
the entire scan. Components with unknown versions cannot be meaningfully
checked for CVEs and should be skipped with a debug log message.

Changes

  • cve_bin_tool/cve_scanner.py: Import UnknownVersion, wrap Version()
    call in try/except, return early with debug log if version is unknown
  • test/test_cve_scanner_unknown_version.py: Regression tests for UNKNOWN,
    unknown (lowercase), empty string, and valid version cases

Copilot AI review requested due to automatic review settings March 20, 2026 14:32
…eption

Signed-off-by: Nancy <9d.24.nancy.sangani@gmail.com>
@nancysangani nancysangani force-pushed the fix/unknown-version-sbom-exception branch from ab77d60 to a16a99b Compare March 20, 2026 14:36
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a crash when scanning SBOM components whose version is "UNKNOWN" by handling UnknownVersion during version parsing and adding regression coverage around unknown/empty versions.

Changes:

  • Catch UnknownVersion when parsing product_info.version in CVEScanner.get_cves() and skip such components with a debug log.
  • Add regression tests covering "UNKNOWN", "unknown", empty string, and a valid version.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
cve_bin_tool/cve_scanner.py Prevents UnknownVersion from terminating scans by skipping unknown/unparseable versions.
test/test_cve_scanner_unknown_version.py Adds regression tests to ensure unknown/empty versions don’t crash scanning.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

except UnknownVersion:
self.logger.debug(
f"Skipping {product_info.product} due to unknown version: {product_info.version!r}"
)
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

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

When UnknownVersion is caught, get_cves() returns before updating all_product_data / all_cve_data and before recording triage_data['paths']. That means components with unknown versions effectively disappear from downstream outputs (e.g., SBOM generation uses all_product_data), rather than being treated as “detected but skipped”. Consider adding the same minimal bookkeeping used in the vendor == 'UNKNOWN' / no_scan early-return paths (populate all_product_data and update paths) before returning.

Suggested change
)
)
# Even when skipping due to unknown version, record that this product was detected
# so that downstream consumers (e.g., SBOM generation) can see it as "detected but skipped".
paths = set(triage_data.get("paths", []))
# Update all_product_data with the observed paths, if this structure is present.
if hasattr(self, "all_product_data"):
product_entry = self.all_product_data.setdefault(
product_info, {"paths": set()}
)
product_entry.setdefault("paths", set()).update(paths)
# Ensure all_cve_data has an entry with no CVEs but with the correct paths.
if hasattr(self, "all_cve_data"):
cve_entry = self.all_cve_data.setdefault(
product_info, {"cves": [], "paths": set()}
)
cve_entry.setdefault("paths", set()).update(paths)

Copilot uses AI. Check for mistakes.
Comment on lines +153 to +154
try:
parsed_version = Version(product_info.version)
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

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

UnknownVersion in version_compare.parse_version() is detected before .strip(), so inputs like ' UNKNOWN ' (leading/trailing whitespace) won’t raise and can lead to incorrect range comparisons / false positives. Consider normalizing product_info.version (e.g., stripping whitespace and applying case-insensitive 'unknown' handling) before constructing Version() so the skip logic is applied consistently.

Suggested change
try:
parsed_version = Version(product_info.version)
version_value = product_info.version
if isinstance(version_value, str):
version_value = version_value.strip()
if version_value.lower() == "unknown":
self.logger.debug(
f"Skipping {product_info.product} due to unknown version: {product_info.version!r}"
)
return
try:
parsed_version = Version(version_value)

Copilot uses AI. Check for mistakes.
Comment on lines +84 to +89
try:
scanner.get_cves(product_info, TRIAGE_DATA_EMPTY)
except Exception as e:
pytest.fail(
f"get_cves raised unexpected exception for valid version: {e}"
) No newline at end of file
Copy link

Copilot AI Mar 20, 2026

Choose a reason for hiding this comment

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

In test_valid_version_still_processed, the try/except Exception + pytest.fail() is redundant—pytest will already fail the test if get_cves() raises. Removing the wrapper (or using an explicit does_not_raise context) will simplify the test and preserve the original exception traceback.

Suggested change
try:
scanner.get_cves(product_info, TRIAGE_DATA_EMPTY)
except Exception as e:
pytest.fail(
f"get_cves raised unexpected exception for valid version: {e}"
)
scanner.get_cves(product_info, TRIAGE_DATA_EMPTY)

Copilot uses AI. Check for mistakes.
…eption

Signed-off-by: Nancy <9d.24.nancy.sangani@gmail.com>
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.

fix: [bug description] Unknown version in a SBOM component results in exception being raised

2 participants