]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-149980: Strip all trailing slashes from GNU long directory names in tarfile (GH...
authorankhikarmakar <100954262+ankhikarmakar@users.noreply.github.com>
Mon, 18 May 2026 19:31:15 +0000 (12:31 -0700)
committerGitHub <noreply@github.com>
Mon, 18 May 2026 19:31:15 +0000 (19:31 +0000)
Lib/tarfile.py
Lib/test/test_tarfile.py
Misc/NEWS.d/next/Library/2026-05-19-12-00-00.gh-issue-149980.Kx7p2A.rst [new file with mode: 0644]

index 772b51295fcfbef724cd62f7586fbb238f47974b..87500c726ce9a8baf14153e892cb72aa530855f3 100644 (file)
@@ -1425,7 +1425,7 @@ class TarInfo(object):
         # Remove redundant slashes from directories. This is to be consistent
         # with frombuf().
         if next.isdir():
-            next.name = next.name.removesuffix("/")
+            next.name = next.name.rstrip("/")
 
         return next
 
index 8e213a8f9992181703b16bc727ad6a35ff5fd738..02fd9620bcf33d8cd81b884a20afe0737b642968 100644 (file)
@@ -1313,6 +1313,27 @@ class GNUReadTest(LongnameTest, ReadTest, unittest.TestCase):
         else:
             return False
 
+    def test_gnulong_dirname_strips_all_trailing_slashes(self):
+        # gh-149980: _proc_gnulong must normalize trailing slashes the same
+        # way _frombuf and _proc_builtin do (rstrip, not removesuffix), so
+        # a GNU long-name directory entry agrees with a short-name one.
+        long_name = "a" * 120 + "///"   # > 100 bytes => GNUTYPE_LONGNAME
+        short_name = "b" * 20 + "///"
+
+        buf = io.BytesIO()
+        with tarfile.open(fileobj=buf, mode="w",
+                          format=tarfile.GNU_FORMAT) as tar:
+            for name in (short_name, long_name):
+                info = tarfile.TarInfo(name=name)
+                info.type = tarfile.DIRTYPE
+                tar.addfile(info)
+
+        buf.seek(0)
+        with tarfile.open(fileobj=buf, mode="r") as tar:
+            names = [m.name for m in tar.getmembers()]
+
+        self.assertEqual(names, ["b" * 20, "a" * 120])
+
 
 class PaxReadTest(LongnameTest, ReadTest, unittest.TestCase):
 
diff --git a/Misc/NEWS.d/next/Library/2026-05-19-12-00-00.gh-issue-149980.Kx7p2A.rst b/Misc/NEWS.d/next/Library/2026-05-19-12-00-00.gh-issue-149980.Kx7p2A.rst
new file mode 100644 (file)
index 0000000..b056f6a
--- /dev/null
@@ -0,0 +1,3 @@
+Fix :mod:`tarfile` so that GNU long-name directory entries have all
+trailing slashes stripped from their names, matching the behavior for
+short-name entries.  Previously, only a single trailing slash was removed.