Skip to content

Commit cc31641

Browse files
authored
gh-151669: Normalize symlink targets in tarfile.TarFile.gettarinfo() (GH-151671)
This applies a normalization when creating members vrom the filesystem, complementary to the one added to tarfile.TarFile.extract() in gh-138309 that does it in the other direction. This solves an issue with round-tripping through the filesystem.
1 parent c98e984 commit cc31641

4 files changed

Lines changed: 23 additions & 1 deletion

File tree

Doc/whatsnew/3.15.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1549,6 +1549,9 @@ tarfile
15491549
now replace slashes with backslashes in symlink targets on Windows to prevent
15501550
creation of corrupted links.
15511551
(Contributed by Christoph Walcher in :gh:`57911`.)
1552+
* :func:`~tarfile.TarFile.gettarinfo` now replaces backslashes with slashes in
1553+
symlink targets on Windows to conform to the tar format standard. (Contributed
1554+
by Daniele Nicolodi in :gh:`151669`.)
15521555

15531556

15541557
threading

Lib/tarfile.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2255,7 +2255,7 @@ def gettarinfo(self, name=None, arcname=None, fileobj=None):
22552255
type = FIFOTYPE
22562256
elif stat.S_ISLNK(stmd):
22572257
type = SYMTYPE
2258-
linkname = os.readlink(name)
2258+
linkname = os.readlink(name).replace(os.sep, "/")
22592259
elif stat.S_ISCHR(stmd):
22602260
type = CHRTYPE
22612261
elif stat.S_ISBLK(stmd):

Lib/test/test_tarfile.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1668,6 +1668,22 @@ def test_symlink_size(self):
16681668
finally:
16691669
os_helper.unlink(path)
16701670

1671+
@os_helper.skip_unless_symlink
1672+
def test_symlink_target_normalization(self):
1673+
# Test for gh-151669.
1674+
path = os.path.join(TEMPDIR, "symlink")
1675+
target = "subdir/link/target"
1676+
os.symlink(target.replace("/", os.sep), path)
1677+
try:
1678+
tar = tarfile.open(tmpname, self.mode)
1679+
try:
1680+
tarinfo = tar.gettarinfo(path)
1681+
self.assertEqual(tarinfo.linkname, target)
1682+
finally:
1683+
tar.close()
1684+
finally:
1685+
os_helper.unlink(path)
1686+
16711687
def test_add_self(self):
16721688
# Test for #1257255.
16731689
dstname = os.path.abspath(tmpname)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
On Windows, when populating tar archives from filesystem content, to
2+
conform to the tar format standard, backslashes in symlink targets are
3+
be replaced by slashes.

0 commit comments

Comments
 (0)