Skip to content

Commit ba27330

Browse files
dnicolodimiss-islington
authored andcommitted
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. (cherry picked from commit cc31641) Co-authored-by: Daniele Nicolodi <daniele@grinta.net>
1 parent 73f534c commit ba27330

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
@@ -1541,6 +1541,9 @@ tarfile
15411541
now replace slashes with backslashes in symlink targets on Windows to prevent
15421542
creation of corrupted links.
15431543
(Contributed by Christoph Walcher in :gh:`57911`.)
1544+
* :func:`~tarfile.TarFile.gettarinfo` now replaces backslashes with slashes in
1545+
symlink targets on Windows to conform to the tar format standard. (Contributed
1546+
by Daniele Nicolodi in :gh:`151669`.)
15441547

15451548

15461549
threading

Lib/tarfile.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2275,7 +2275,7 @@ def gettarinfo(self, name=None, arcname=None, fileobj=None):
22752275
type = FIFOTYPE
22762276
elif stat.S_ISLNK(stmd):
22772277
type = SYMTYPE
2278-
linkname = os.readlink(name)
2278+
linkname = os.readlink(name).replace(os.sep, "/")
22792279
elif stat.S_ISCHR(stmd):
22802280
type = CHRTYPE
22812281
elif stat.S_ISBLK(stmd):

Lib/test/test_tarfile.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1647,6 +1647,22 @@ def test_symlink_size(self):
16471647
finally:
16481648
os_helper.unlink(path)
16491649

1650+
@os_helper.skip_unless_symlink
1651+
def test_symlink_target_normalization(self):
1652+
# Test for gh-151669.
1653+
path = os.path.join(TEMPDIR, "symlink")
1654+
target = "subdir/link/target"
1655+
os.symlink(target.replace("/", os.sep), path)
1656+
try:
1657+
tar = tarfile.open(tmpname, self.mode)
1658+
try:
1659+
tarinfo = tar.gettarinfo(path)
1660+
self.assertEqual(tarinfo.linkname, target)
1661+
finally:
1662+
tar.close()
1663+
finally:
1664+
os_helper.unlink(path)
1665+
16501666
def test_add_self(self):
16511667
# Test for #1257255.
16521668
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)