]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-91387: Strip trailing slash from tarfile longname directories (GH-32423)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Tue, 21 Jun 2022 18:09:55 +0000 (11:09 -0700)
committerGitHub <noreply@github.com>
Tue, 21 Jun 2022 18:09:55 +0000 (11:09 -0700)
Co-authored-by: Brett Cannon <brett@python.org>
(cherry picked from commit c1e19421c23d1261ecbbe7375316adc1c24f0a87)

Co-authored-by: Chris Fernald <chrisf671@gmail.com>
Lib/tarfile.py
Lib/test/test_tarfile.py
Misc/NEWS.d/next/Library/2022-04-08-22-12-11.bpo-47231.lvyglt.rst [new file with mode: 0644]

index 6ada9a05db9cbe4c180e89e56dd4c651cd64320a..dea150e8dbbb62faa431fdc776157d7886bbac89 100755 (executable)
@@ -1163,6 +1163,11 @@ class TarInfo(object):
         # header information.
         self._apply_pax_info(tarfile.pax_headers, tarfile.encoding, tarfile.errors)
 
+        # Remove redundant slashes from directories. This is to be consistent
+        # with frombuf().
+        if self.isdir():
+            self.name = self.name.rstrip("/")
+
         return self
 
     def _proc_gnulong(self, tarfile):
@@ -1185,6 +1190,11 @@ class TarInfo(object):
         elif self.type == GNUTYPE_LONGLINK:
             next.linkname = nts(buf, tarfile.encoding, tarfile.errors)
 
+        # Remove redundant slashes from directories. This is to be consistent
+        # with frombuf().
+        if next.isdir():
+            next.name = next.name.removesuffix("/")
+
         return next
 
     def _proc_sparse(self, tarfile):
index 4bf1ba38f5ea5ad54d7036aa8a44cca58c04a9a6..c658cca7a7806a231febb1ff8bc75edf2d33c82e 100644 (file)
@@ -228,6 +228,7 @@ class UstarReadTest(ReadTest, unittest.TestCase):
     def add_dir_and_getmember(self, name):
         with os_helper.temp_cwd():
             with tarfile.open(tmpname, 'w') as tar:
+                tar.format = tarfile.USTAR_FORMAT
                 try:
                     os.mkdir(name)
                     tar.add(name)
@@ -1006,11 +1007,26 @@ class LongnameTest:
                                               "iso8859-1", "strict")
             self.assertEqual(tarinfo.type, self.longnametype)
 
+    def test_longname_directory(self):
+        # Test reading a longlink directory. Issue #47231.
+        longdir = ('a' * 101) + '/'
+        with os_helper.temp_cwd():
+            with tarfile.open(tmpname, 'w') as tar:
+                tar.format = self.format
+                try:
+                    os.mkdir(longdir)
+                    tar.add(longdir)
+                finally:
+                    os.rmdir(longdir)
+            with tarfile.open(tmpname) as tar:
+                self.assertIsNotNone(tar.getmember(longdir))
+                self.assertIsNotNone(tar.getmember(longdir.removesuffix('/')))
 
 class GNUReadTest(LongnameTest, ReadTest, unittest.TestCase):
 
     subdir = "gnu"
     longnametype = tarfile.GNUTYPE_LONGNAME
+    format = tarfile.GNU_FORMAT
 
     # Since 3.2 tarfile is supposed to accurately restore sparse members and
     # produce files with holes. This is what we actually want to test here.
@@ -1070,6 +1086,7 @@ class PaxReadTest(LongnameTest, ReadTest, unittest.TestCase):
 
     subdir = "pax"
     longnametype = tarfile.XHDTYPE
+    format = tarfile.PAX_FORMAT
 
     def test_pax_global_headers(self):
         tar = tarfile.open(tarname, encoding="iso8859-1")
diff --git a/Misc/NEWS.d/next/Library/2022-04-08-22-12-11.bpo-47231.lvyglt.rst b/Misc/NEWS.d/next/Library/2022-04-08-22-12-11.bpo-47231.lvyglt.rst
new file mode 100644 (file)
index 0000000..ee05c5e
--- /dev/null
@@ -0,0 +1 @@
+Fixed an issue with inconsistent trailing slashes in tarfile longname directories.