Skip to content

Commit 5775aa8

Browse files
gh-149980: Strip all trailing slashes from GNU long directory names in tarfile (GH-150019)
1 parent 6d5be4b commit 5775aa8

3 files changed

Lines changed: 25 additions & 1 deletion

File tree

Lib/tarfile.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1425,7 +1425,7 @@ def _proc_gnulong(self, tarfile):
14251425
# Remove redundant slashes from directories. This is to be consistent
14261426
# with frombuf().
14271427
if next.isdir():
1428-
next.name = next.name.removesuffix("/")
1428+
next.name = next.name.rstrip("/")
14291429

14301430
return next
14311431

Lib/test/test_tarfile.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1313,6 +1313,27 @@ def _fs_supports_holes():
13131313
else:
13141314
return False
13151315

1316+
def test_gnulong_dirname_strips_all_trailing_slashes(self):
1317+
# gh-149980: _proc_gnulong must normalize trailing slashes the same
1318+
# way _frombuf and _proc_builtin do (rstrip, not removesuffix), so
1319+
# a GNU long-name directory entry agrees with a short-name one.
1320+
long_name = "a" * 120 + "///" # > 100 bytes => GNUTYPE_LONGNAME
1321+
short_name = "b" * 20 + "///"
1322+
1323+
buf = io.BytesIO()
1324+
with tarfile.open(fileobj=buf, mode="w",
1325+
format=tarfile.GNU_FORMAT) as tar:
1326+
for name in (short_name, long_name):
1327+
info = tarfile.TarInfo(name=name)
1328+
info.type = tarfile.DIRTYPE
1329+
tar.addfile(info)
1330+
1331+
buf.seek(0)
1332+
with tarfile.open(fileobj=buf, mode="r") as tar:
1333+
names = [m.name for m in tar.getmembers()]
1334+
1335+
self.assertEqual(names, ["b" * 20, "a" * 120])
1336+
13161337

13171338
class PaxReadTest(LongnameTest, ReadTest, unittest.TestCase):
13181339

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fix :mod:`tarfile` so that GNU long-name directory entries have all
2+
trailing slashes stripped from their names, matching the behavior for
3+
short-name entries. Previously, only a single trailing slash was removed.

0 commit comments

Comments
 (0)