Skip to content

Commit 382e7c4

Browse files
committed
gh-57911: Sanitize symlink targets in tarfile on win32
1 parent 15e37ea commit 382e7c4

File tree

3 files changed

+25
-1
lines changed

3 files changed

+25
-1
lines changed

Lib/tarfile.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2718,7 +2718,13 @@ def makelink_with_filter(self, tarinfo, targetpath,
27182718
if os.path.lexists(targetpath):
27192719
# Avoid FileExistsError on following os.symlink.
27202720
os.unlink(targetpath)
2721-
os.symlink(tarinfo.linkname, targetpath)
2721+
link_target = tarinfo.linkname
2722+
if os.name == "nt":
2723+
# gh-57911: Posix-flavoured forward-slash path separators in
2724+
# symlink targets aren't sanitized by Windows automaticly,
2725+
# resulting in corrupted links.
2726+
link_target = link_target.replace("/", os.path.sep)
2727+
os.symlink(link_target, targetpath)
27222728
return
27232729
else:
27242730
if os.path.exists(tarinfo._link_target):

Lib/test/test_tarfile.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4039,6 +4039,21 @@ def test_absolute_symlink(self):
40394039
tarfile.AbsoluteLinkError,
40404040
"'parent' is a link to an absolute path")
40414041

4042+
@unittest.skipUnless(os_helper.can_symlink(), 'requires symlink support')
4043+
@symlink_test
4044+
def test_symlink_target_sanitized_on_windows(self):
4045+
with ArchiveMaker() as arc:
4046+
arc.add('link', symlink_to="relative/test/path")
4047+
4048+
with self.check_context(arc.open(), 'fully_trusted'):
4049+
self.expect_file('link', type=tarfile.SYMTYPE)
4050+
link_path = os.path.normpath(self.destdir / "link")
4051+
link_target = os.readlink(link_path)
4052+
if os.name == "nt":
4053+
self.assertEqual(link_target, "relative\\test\\path")
4054+
else:
4055+
self.assertEqual(link_target, "relative/test/path")
4056+
40424057
def test_absolute_hardlink(self):
40434058
# Test hardlink to an absolute path
40444059
# Inspired by 'dirsymlink' in https://github.com/jwilk/traversal-archives
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
When extracting tar files on Windows the path of symlink targets will be
2+
sanitized to use backward-slashes as path separator because Posix flavoured
3+
path separators result in corrupted links.

0 commit comments

Comments
 (0)