Skip to content

Commit 7f2a979

Browse files
author
user
committed
normpath linkname
1 parent bbe7cc7 commit 7f2a979

File tree

3 files changed

+40
-3
lines changed

3 files changed

+40
-3
lines changed

news/13550.bugfix.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
Add the _check_link_targetfunction to validate the file pointed to by a symlink. If path traversal
2-
is detected, it should raise an InstallationErrorexception, similar to is_within_directory.
1+
Add the _check_link_targetfunction to validate the file pointed to by a symlink. If path traversal
2+
is detected, it should raise an InstallationErrorexception, similar to is_within_directory.

src/pip/_internal/utils/unpacking.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,8 @@ def _check_link_target(tar: tarfile.TarFile, tarinfo: tarfile.TarInfo) -> None:
261261
filter(None, (os.path.dirname(tarinfo.name), tarinfo.linkname))
262262
)
263263

264+
linkname = os.path.normpath(linkname)
265+
264266
try:
265267
tar.getmember(linkname)
266268
except KeyError:

tests/unit/test_utils_unpacking.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ def test_unpack_tar_links(self, input_prefix: str, unpack_prefix: str) -> None:
239239
with open(os.path.join(unpack_dir, "symlink.txt"), "rb") as f:
240240
assert f.read() == content
241241

242-
def test_unpack_normal_tar_links_no_data_filter(
242+
def test_unpack_normal_tar_link1_no_data_filter(
243243
self, monkeypatch: MonkeyPatch
244244
) -> None:
245245
"""
@@ -274,6 +274,41 @@ def test_unpack_normal_tar_links_no_data_filter(
274274
with open(os.path.join(extract_path, "normal_symlink"), "rb") as f:
275275
assert f.read() == b"normal\n"
276276

277+
def test_unpack_normal_tar_link2_no_data_filter(
278+
self, monkeypatch: MonkeyPatch
279+
) -> None:
280+
"""
281+
Test unpacking a normal tar with file containing soft links, but no data_filter
282+
"""
283+
if hasattr(tarfile, "data_filter"):
284+
monkeypatch.delattr("tarfile.data_filter")
285+
286+
tar_filename = "test_tar_links_no_data_filter.tar"
287+
tar_filepath = os.path.join(self.tempdir, tar_filename)
288+
289+
extract_path = os.path.join(self.tempdir, "extract_path")
290+
291+
with tarfile.open(tar_filepath, "w") as tar:
292+
file_data = io.BytesIO(b"normal\n")
293+
normal_file_tarinfo = tarfile.TarInfo(name="normal_file")
294+
normal_file_tarinfo.size = len(file_data.getbuffer())
295+
tar.addfile(normal_file_tarinfo, fileobj=file_data)
296+
297+
info = tarfile.TarInfo("sub/normal_symlink")
298+
info.type = tarfile.SYMTYPE
299+
info.linkpath = ".." + os.path.sep + "normal_file"
300+
tar.addfile(info)
301+
302+
untar_file(tar_filepath, extract_path)
303+
304+
assert os.path.islink(os.path.join(extract_path, "sub", "normal_symlink"))
305+
306+
link_path = os.readlink(os.path.join(extract_path, "sub", "normal_symlink"))
307+
assert link_path == ".." + os.path.sep + "normal_file"
308+
309+
with open(os.path.join(extract_path, "sub", "normal_symlink"), "rb") as f:
310+
assert f.read() == b"normal\n"
311+
277312
def test_unpack_evil_tar_link1_no_data_filter(
278313
self, monkeypatch: MonkeyPatch
279314
) -> None:

0 commit comments

Comments
 (0)