Skip to content

Commit 851f30e

Browse files
authored
fix: add tarfile test, minor tarfile refactor (#3962)
This adds a tarfile with an absolute path file in it for testing and switches our file open to use a with construction. (This helps with some experiments we're doing to improve the safety of tarfile extraction in windows.) Signed-off-by: Terri Oda <[email protected]>
1 parent bf18cf6 commit 851f30e

File tree

3 files changed

+23
-10
lines changed

3 files changed

+23
-10
lines changed

cve_bin_tool/extractor.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -131,26 +131,27 @@ async def extract_file_tar(self, filename, extraction_path):
131131
# make sure we have full path for later checks
132132
extraction_path = str(Path(extraction_path).resolve())
133133
with ErrorHandler(mode=ErrorMode.Ignore) as e:
134-
tar = tarfile.open(filename)
135134
# Python 3.12 has a data filter we can use in extract
136135
# tarfile has this available in older versions as well
137136
if hasattr(tarfile, "data_filter"):
138-
tar.extractall(path=extraction_path, filter="data") # nosec
137+
with tarfile.open(filename) as tar:
138+
tar.extractall(path=extraction_path, filter="data") # nosec
139139
# nosec line because bandit doesn't understand filters yet
140140

141-
# FIXME: the backported fix is not working on windows.
142-
# this leaves the current (unsafe) behaviour so we can fix at least one OS for now
143141
elif sys.platform == "win32":
144-
tar.extractall(path=extraction_path) # nosec
142+
# use unsafe extraction for now, fix will come in separate PR
143+
with tarfile.open(filename) as tar:
144+
tar.extractall(path=extraction_path) # nosec - fix in progress
145145

146146
# Some versions may need us to implement a filter to avoid unsafe behaviour
147147
# we could consider logging a warning here
148148
else:
149-
tar.extractall(
150-
path=extraction_path,
151-
members=self.tar_member_filter(tar, extraction_path),
152-
) # nosec
153-
tar.close()
149+
with tarfile.open(filename) as tar:
150+
tar.extractall(
151+
path=extraction_path,
152+
members=self.tar_member_filter(tar, extraction_path),
153+
) # nosec
154+
154155
return e.exit_code
155156

156157
async def extract_file_rpm(self, filename, extraction_path):

test/assets/tarfile_abs_test.tar

10 KB
Binary file not shown.

test/test_extractor.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,18 @@ async def test_extract_file_tar(self, extension_list: list[str]):
116116
):
117117
assert Path(dir_path).is_dir()
118118

119+
@pytest.mark.asyncio
120+
async def test_extract_file_tar_absolute(self):
121+
"""Test against a tarfile with absolute file names.
122+
It should not extract to /tmp/cve-bin-tool_tarfile_test.txt"""
123+
124+
abs_tar_test = (
125+
Path(__file__).parent.resolve() / "assets" / "tarfile_abs_test.tar"
126+
)
127+
self.extract_files(abs_tar_test)
128+
assert not Path("/tmp/cve-bin-tool_tarfile_abs_test.txt").is_file() # nosec
129+
# Bandit note: intentional hard-coded value for this test of absolute file extraction
130+
119131
@pytest.mark.asyncio
120132
async def test_extract_cleanup(self):
121133
"""Make sure tar extractor cleans up after itself"""

0 commit comments

Comments
 (0)