Skip to content

Commit a1678b7

Browse files
terrikopdxjohnny
authored andcommitted
fix!: Make error codes fit standard range
Previously, cve-bin-tool returned the number of CVEs found, or negative numbers for error codes. Because error codes are expected to be in the range 0-127 that could cause unexpected behaviours (particularly on Windows) so this PR changes our error codes to be positive values. error code 1 is reserved to indicate the cves were found error codes 2+ indicate operational errors. Signed-off-by: Terri Oda <[email protected]> BREAKING CHANGE: Error codes
1 parent b141f3d commit a1678b7

File tree

3 files changed

+49
-36
lines changed

3 files changed

+49
-36
lines changed

cve_bin_tool/cli.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -554,10 +554,19 @@ def main(argv=None):
554554
)
555555
fixes.check_available_fix()
556556

557-
# Use the number of products with known cves as error code
558-
# as requested by folk planning to automate use of this script.
559-
# If no cves found, then the program exits cleanly.
560-
return cve_scanner.products_with_cve
557+
# If no cves found, then the program exits cleanly (0 exit)
558+
if cve_scanner.products_with_cve == 0:
559+
return 0
560+
561+
# if some cves are found, return with exit code 1
562+
# Previously this returned a number of CVEs found, but that can
563+
# exceed expected return value range.
564+
if cve_scanner.products_with_cve > 0:
565+
return 1
566+
567+
# If somehow we got negative numbers of cves something has gone
568+
# horribly wrong. Since return code 2 is used by argparse, use 3
569+
return 3
561570

562571

563572
if __name__ == "__main__":

cve_bin_tool/error_handler.py

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -166,27 +166,31 @@ def __exit__(self, exc_type, exc_val, exc_tb):
166166
return False
167167

168168

169-
# Exit codes for Exception. exit code -1 is reserved for unknown exceptions.
169+
# Exit codes for Exception.
170+
# Error code 1 is reserved to mean that cves were found
171+
# Error code 2 is reserved for argparse errors (default argparse behaviour)
172+
# Error code 3 is reserved for "we found negative cves" (should be impossible)
173+
# Error code 4-20 are reserved just in case
170174
ERROR_CODES = {
171-
SystemExit: -2,
172-
FileNotFoundError: -3,
173-
InvalidCsvError: -4,
174-
InvalidJsonError: -4,
175-
EmptyTxtError: -4,
176-
InvalidListError: -4,
177-
MissingFieldsError: -5,
178-
InsufficientArgs: -6,
179-
EmptyCache: -7,
180-
CVEDataForYearNotInCache: -8,
181-
CVEDataForCurlVersionNotInCache: -9,
182-
AttemptedToWriteOutsideCachedir: -10,
183-
SHAMismatch: -11,
184-
ExtractionFailed: -12,
185-
UnknownArchiveType: -13,
186-
UnknownConfigType: -14,
187-
CVEDataMissing: -15,
188-
InvalidCheckerError: -16,
189-
NVDRateLimit: -17,
190-
InvalidIntermediateJsonError: -18,
191-
NVDServiceError: -19,
175+
SystemExit: 2,
176+
FileNotFoundError: 21,
177+
InvalidCsvError: 22,
178+
InvalidJsonError: 22,
179+
EmptyTxtError: 22,
180+
InvalidListError: 22,
181+
MissingFieldsError: 23,
182+
InsufficientArgs: 24,
183+
EmptyCache: 25,
184+
CVEDataForYearNotInCache: 26,
185+
CVEDataForCurlVersionNotInCache: 27,
186+
AttemptedToWriteOutsideCachedir: 28,
187+
SHAMismatch: 29,
188+
ExtractionFailed: 30,
189+
UnknownArchiveType: 31,
190+
UnknownConfigType: 32,
191+
CVEDataMissing: 33,
192+
InvalidCheckerError: 34,
193+
NVDRateLimit: 35,
194+
InvalidIntermediateJsonError: 36,
195+
NVDServiceError: 37,
192196
}

test/test_cli.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -88,37 +88,37 @@ def test_usage(self):
8888
"""Test that the usage returns 0"""
8989
with pytest.raises(SystemExit) as e:
9090
main(["cve-bin-tool"])
91-
assert e.value.args[0] == -6
91+
assert e.value.args[0] == 24
9292

9393
def test_invalid_file_or_directory(self):
9494
"""Test behaviour with an invalid file/directory"""
9595
with pytest.raises(SystemExit) as e:
9696
main(["cve-bin-tool", "non-existant"])
97-
assert e.value.args[0] == -3
97+
assert e.value.args[0] == 21
9898

9999
def test_invalid_parameter(self):
100100
"""Test that invalid parmeters exit with expected error code.
101-
ArgParse calls sys.exit(2) for all errors, we've overwritten to -2"""
101+
ArgParse calls sys.exit(2) for all errors """
102102

103103
# no directory specified
104104
with pytest.raises(SystemExit) as e:
105105
main(["cve-bin-tool", "--bad-param"])
106-
assert e.value.args[0] == -2
106+
assert e.value.args[0] == 2
107107

108108
# bad parameter (but good directory)
109109
with pytest.raises(SystemExit) as e:
110110
main(["cve-bin-tool", "--bad-param", self.tempdir])
111-
assert e.value.args[0] == -2
111+
assert e.value.args[0] == 2
112112

113113
# worse parameter
114114
with pytest.raises(SystemExit) as e:
115115
main(["cve-bin-tool", "--bad-param && cat hi", self.tempdir])
116-
assert e.value.args[0] == -2
116+
assert e.value.args[0] == 2
117117

118118
# bad parameter after directory
119119
with pytest.raises(SystemExit) as e:
120120
main(["cve-bin-tool", self.tempdir, "--bad-param;cat hi"])
121-
assert e.value.args[0] == -2
121+
assert e.value.args[0] == 2
122122

123123
@unittest.skipUnless(LONG_TESTS() > 0, "Skipping long tests")
124124
def test_update_flags(self):
@@ -136,7 +136,7 @@ def test_update_flags(self):
136136
)
137137
with pytest.raises(SystemExit) as e:
138138
main(["cve-bin-tool", "-u", "whatever", "-n", "json", self.tempdir])
139-
assert e.value.args[0] == -2
139+
assert e.value.args[0] == 2
140140

141141
@staticmethod
142142
def check_exclude_log(caplog, exclude_path, checkers):
@@ -349,11 +349,11 @@ def test_severity(self, capsys, caplog):
349349
# Check command line parameters - wrong case
350350
with pytest.raises(SystemExit) as e:
351351
main(["cve-bin-tool", "-S", "HIGH", self.tempdir])
352-
assert e.value.args[0] == -2
352+
assert e.value.args[0] == 2
353353
# Check command line parameters - wrong option
354354
with pytest.raises(SystemExit) as e:
355355
main(["cve-bin-tool", "-S", "ALL", self.tempdir])
356-
assert e.value.args[0] == -2
356+
assert e.value.args[0] == 2
357357

358358
my_test_filename = "sevtest.csv"
359359

0 commit comments

Comments
 (0)