Skip to content

Commit 1249208

Browse files
committed
feat(vex): fix failing tests
1 parent e9dcb6a commit 1249208

File tree

3 files changed

+63
-2
lines changed

3 files changed

+63
-2
lines changed

cve_bin_tool/util.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,9 @@ def decode_bom_ref(ref: str):
421421
urn_cdx_with_purl = re.compile(
422422
r"urn:cdx:(?P<bomSerialNumber>[^/]+)\/(?P<bom_version>[^#]+)#(?P<purl>pkg:[^\s]+)"
423423
)
424+
424425
location = "location/to/product"
426+
425427
match = (
426428
urn_cdx_with_purl.match(ref)
427429
or urn_cbt_ext_ref.match(ref)

cve_bin_tool/vex_manager/parse.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,66 @@ def __init__(self, filename: str, vextype: str, logger=None):
3535
self.parsed_data = defaultdict(dict)
3636
self.serialNumbers = set()
3737
self.vex_handler = VexHandler(self.logger)
38+
self.vex_product_info = {}
3839

3940
def parse_vex(self) -> DefaultDict[ProductInfo, TriageData]:
4041
"""Parses the VEX file and extracts the necessary fields from the vulnerabilities."""
4142
# Use VexHandler to parse the VEX file
4243
self.parsed_data = self.vex_handler.parse(self.filename, self.vextype)
44+
self._extract_product_info()
4345
return self.parsed_data
46+
47+
def _extract_product_info(self):
48+
"""Extracts the product information from the parsed VEX file"""
49+
product_info = {}
50+
51+
# Try to get metadata from the VEX handler
52+
try:
53+
# Get the actual VEX type that was detected
54+
detected_type = self.vex_handler._detect_vex_type(self.filename)
55+
if detected_type:
56+
self.vextype = detected_type
57+
58+
# For CycloneDX, try to extract metadata from the parsed file
59+
if self.vextype == "cyclonedx":
60+
import json
61+
62+
try:
63+
with open(self.filename, encoding="utf-8") as f:
64+
vex_data = json.load(f)
65+
66+
metadata = vex_data.get("metadata", {})
67+
component = metadata.get("component", {})
68+
69+
product_info["product"] = component.get("name", "")
70+
product_info["release"] = component.get("version", "")
71+
product_info["vendor"] = component.get("supplier", {}).get(
72+
"name", ""
73+
)
74+
75+
except (json.JSONDecodeError, FileNotFoundError, KeyError) as e:
76+
self.logger.warning(
77+
f"Could not extract product info from CycloneDX VEX: {e}"
78+
)
79+
80+
elif self.vextype == "csaf":
81+
# For CSAF, product info would be in the document
82+
product_info["product"] = ""
83+
product_info["release"] = ""
84+
product_info["vendor"] = ""
85+
86+
elif self.vextype == "openvex":
87+
# For OpenVEX, limited product info available
88+
product_info["product"] = ""
89+
product_info["release"] = ""
90+
product_info["vendor"] = ""
91+
92+
except Exception as e:
93+
self.logger.debug(f"Error extracting product info: {e}")
94+
95+
# Set default values if not found
96+
for key in ["product", "release", "vendor"]:
97+
if key not in product_info:
98+
product_info[key] = ""
99+
100+
self.vex_product_info = product_info

test/test_vex.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,8 @@ def test_triage(self):
368368
)
369369

370370
# Check if the command succeeded
371-
if result.returncode != 0:
371+
# Exit code 1 is expected when CVEs are found, 0 when none are found
372+
if result.returncode not in [0, 1]:
372373
print(f"Command failed with return code {result.returncode}")
373374
print(f"STDOUT: {result.stdout}")
374375
print(f"STDERR: {result.stderr}")
@@ -428,7 +429,8 @@ def test_filter_triage(self):
428429
)
429430

430431
# Check if the command succeeded
431-
if result.returncode != 0:
432+
# Exit code 1 is expected when CVEs are found, 0 when none are found
433+
if result.returncode not in [0, 1]:
432434
print(f"Command failed with return code {result.returncode}")
433435
print(f"STDOUT: {result.stdout}")
434436
print(f"STDERR: {result.stderr}")

0 commit comments

Comments
 (0)