Skip to content

Commit c59155c

Browse files
authored
fix: Change extraction exceptions to logged warnings (#2408)
* fixes #1748 Currently, when files can't be extracted because a tool is not installed, we throw an exception and halt the scan. This is great for getting attention but terrible if you're scanning a large system and maybe just don't care about scanning those files. It also causes a problem in the issue linked above when attempting to run cve-bin-tool on a system outside of the ones we actually support. This PR switches us to logging a message and allowing the scan to proceed.
1 parent 4c4cbd1 commit c59155c

File tree

2 files changed

+30
-29
lines changed

2 files changed

+30
-29
lines changed

cve_bin_tool/extractor.py

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,7 @@
2828
run_coroutine,
2929
)
3030

31-
from .error_handler import (
32-
ErrorHandler,
33-
ErrorMode,
34-
ExtractionFailed,
35-
ExtractionToolNotFound,
36-
UnknownArchiveType,
37-
)
31+
from .error_handler import ErrorHandler, ErrorMode, ExtractionFailed, UnknownArchiveType
3832
from .log import LOGGER
3933

4034
# Run rpmfile in a thread
@@ -107,7 +101,9 @@ async def extract_file_rpm(self, filename, extraction_path):
107101
else:
108102
if not await aio_inpath("7z"):
109103
with ErrorHandler(mode=self.error_mode, logger=self.logger):
110-
raise ExtractionToolNotFound("7z is required to extract rpm files")
104+
# ExtractionToolNotFound
105+
self.logger.error(f"No extraction tool found for {filename}")
106+
self.logger.error("rpm2cpio or 7z can be used to extract rpm files")
111107
else:
112108
stdout, stderr, _ = await aio_run_command(["7z", "x", filename])
113109
if stderr or not stdout:
@@ -152,7 +148,9 @@ async def extract_file_zst(self, filename: str, extraction_path: str) -> int:
152148
if stderr:
153149
return 1
154150
else:
155-
raise ExtractionToolNotFound(
151+
# ExtractionToolNotFound
152+
self.logger.error(f"No extraction tool found for {filename}")
153+
self.logger.error(
156154
"tar or 7zip-zstd is required to extract tar.zstd files"
157155
)
158156
return e.exit_code
@@ -205,9 +203,9 @@ async def extract_file_deb(self, filename, extraction_path):
205203
if is_ar:
206204
if not await aio_inpath("ar"):
207205
with ErrorHandler(mode=self.error_mode, logger=self.logger):
208-
raise ExtractionToolNotFound(
209-
"'ar' is required to extract deb files"
210-
)
206+
# ExtractionToolNotFound
207+
self.logger.error(f"No extraction tool found for {filename}")
208+
self.logger.error("'ar' is required to extract deb files")
211209
else:
212210
stdout, stderr, _ = await aio_run_command(["ar", "x", filename])
213211
if stderr:
@@ -264,9 +262,9 @@ async def extract_file_cab(self, filename, extraction_path):
264262
if sys.platform.startswith("linux"):
265263
if not await aio_inpath("cabextract"):
266264
with ErrorHandler(mode=self.error_mode, logger=self.logger):
267-
raise ExtractionToolNotFound(
268-
"'cabextract' is required to extract cab files"
269-
)
265+
# ExtractionToolNotFound
266+
self.logger.error(f"No extraction tool found for {filename}")
267+
self.logger.error("'cabextract' is required to extract cab files")
270268
else:
271269
stdout, stderr, _ = await aio_run_command(
272270
["cabextract", "-d", extraction_path, filename]
@@ -276,9 +274,9 @@ async def extract_file_cab(self, filename, extraction_path):
276274
else:
277275
if not await aio_inpath("Expand"):
278276
with ErrorHandler(mode=self.error_mode, logger=self.logger):
279-
raise ExtractionToolNotFound(
280-
"'Expand' is required to extract cab files"
281-
)
277+
# ExtractionToolNotFound
278+
self.logger.error(f"No extraction tool found for {filename}")
279+
self.logger.error("'Expand' is required to extract cab files")
282280
else:
283281
stdout, stderr, _ = await aio_run_command(
284282
["Expand", filename, "-R -F:*", extraction_path]

test/test_extractor.py

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
import pytest
2828
from pytest_mock import MockerFixture
2929

30-
from cve_bin_tool.error_handler import ERROR_CODES, ExtractionToolNotFound
3130
from cve_bin_tool.extractor import Extractor
3231
from cve_bin_tool.util import inpath
3332

@@ -285,11 +284,14 @@ async def test_extract_file_deb_no_tool(
285284
coroutine(mocker.Mock(return_value=False)),
286285
)
287286

288-
with pytest.raises(SystemExit) as e:
289-
async for _ in self.extract_files(
290-
[f"test{extension}" for extension in extension_list]
291-
):
292-
assert e.value.args[0] == ERROR_CODES[ExtractionToolNotFound]
287+
# will not extract file, but also won't raise an exception
288+
# we could also check log messages?
289+
async for extracted_path in self.extract_files(
290+
[f"test{extension}" for extension in extension_list]
291+
):
292+
assert not (
293+
Path(extracted_path) / "usr" / "bin" / "cve_bin_tool_deb_test"
294+
).is_file()
293295

294296

295297
class TestExtractFileIpk(TestExtractorBase):
@@ -349,11 +351,12 @@ async def test_extract_file_cab_no_cabextract(
349351
coroutine(mocker.Mock(return_value=False)),
350352
)
351353

352-
with pytest.raises(SystemExit) as e:
353-
async for _ in self.extract_files(
354-
[f"test{extension}" for extension in extension_list]
355-
):
356-
assert e.value.args[0] == ERROR_CODES[ExtractionToolNotFound]
354+
# will not raise exception but also will not extract file
355+
# could also check log messages here?
356+
async for extracted_path in self.extract_files(
357+
[f"test{extension}" for extension in extension_list]
358+
):
359+
assert not (Path(extracted_path) / "usr" / "bin" / "python3.8").is_file()
357360

358361

359362
class TestExtractFileZip(TestExtractorBase):

0 commit comments

Comments
 (0)