1+ # Copyright (C) 2021 Intel Corporation
2+ # SPDX-License-Identifier: GPL-3.0-or-later
3+
4+ """
5+ Tests for CVEScanner graceful handling of UNKNOWN or empty versions.
6+
7+ Regression tests for https://github.com/ossf/cve-bin-tool/issues/5302
8+ A SBOM component with version "UNKNOWN" previously raised an UnknownVersion
9+ exception that terminated the entire scan. Components with unknown versions
10+ should be silently skipped instead.
11+ """
12+ from __future__ import annotations
13+
14+ from unittest .mock import MagicMock
15+
16+ import pytest
17+
18+ from cve_bin_tool .cve_scanner import CVEScanner
19+ from cve_bin_tool .util import ProductInfo
20+
21+
22+ TRIAGE_DATA_EMPTY : dict = {"paths" : {"" }}
23+
24+
25+ def make_scanner () -> CVEScanner :
26+ """Create a CVEScanner instance with a mocked cursor for unit testing."""
27+ scanner = CVEScanner (score = 0 )
28+ scanner .cursor = MagicMock ()
29+ scanner .cursor .fetchall .return_value = []
30+ scanner .cursor .__iter__ = MagicMock (return_value = iter ([]))
31+ return scanner
32+
33+
34+ class TestCVEScannerUnknownVersion :
35+ """Tests that CVEScanner skips components with UNKNOWN or empty versions."""
36+
37+ def test_unknown_version_does_not_raise (self ):
38+ """SBOM component with version 'UNKNOWN' should be skipped, not crash.
39+
40+ Regression test for https://github.com/ossf/cve-bin-tool/issues/5302
41+ """
42+ scanner = make_scanner ()
43+ product_info = ProductInfo (
44+ vendor = "tools" ,
45+ product = "tools" ,
46+ version = "UNKNOWN" ,
47+ )
48+ # Should not raise UnknownVersion exception
49+ scanner .get_cves (product_info , TRIAGE_DATA_EMPTY )
50+ # Component must be skipped - not added to cve_data
51+ assert product_info not in scanner .all_cve_data
52+
53+ def test_unknown_version_lowercase_does_not_raise (self ):
54+ """SBOM component with version 'unknown' (lowercase) should be skipped."""
55+ scanner = make_scanner ()
56+ product_info = ProductInfo (
57+ vendor = "tools" ,
58+ product = "tools" ,
59+ version = "unknown" ,
60+ )
61+ scanner .get_cves (product_info , TRIAGE_DATA_EMPTY )
62+ assert product_info not in scanner .all_cve_data
63+
64+ def test_empty_version_does_not_raise (self ):
65+ """SBOM component with empty version string should be skipped, not crash."""
66+ scanner = make_scanner ()
67+ product_info = ProductInfo (
68+ vendor = "tools" ,
69+ product = "tools" ,
70+ version = "" ,
71+ )
72+ scanner .get_cves (product_info , TRIAGE_DATA_EMPTY )
73+ assert product_info not in scanner .all_cve_data
74+
75+ def test_valid_version_still_processed (self ):
76+ """Components with a valid version string should still be processed normally."""
77+ scanner = make_scanner ()
78+ product_info = ProductInfo (
79+ vendor = "haxx" ,
80+ product = "curl" ,
81+ version = "7.34.0" ,
82+ )
83+ # Should not raise - valid version proceeds normally
84+ try :
85+ scanner .get_cves (product_info , TRIAGE_DATA_EMPTY )
86+ except Exception as e :
87+ pytest .fail (
88+ f"get_cves raised unexpected exception for valid version: { e } "
89+ )
0 commit comments