From 09005630c016d86683ae3d63d3149d4177f6aa70 Mon Sep 17 00:00:00 2001 From: Chris Fernald Date: Fri, 8 Apr 2022 15:07:03 -0700 Subject: [PATCH 1/3] bpo-47231: Strip trailing slash from tarfile longname directories --- Lib/tarfile.py | 10 ++++++++++ Lib/test/test_tarfile.py | 17 +++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/Lib/tarfile.py b/Lib/tarfile.py index 8d43d0da7b9880..7a4880565b8891 100755 --- a/Lib/tarfile.py +++ b/Lib/tarfile.py @@ -1163,6 +1163,11 @@ def _proc_builtin(self, tarfile): # 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 @@ def _proc_gnulong(self, tarfile): 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.rstrip("/") + return next def _proc_sparse(self, tarfile): diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py index 12850cd635e995..c7004698246a41 100644 --- a/Lib/test/test_tarfile.py +++ b/Lib/test/test_tarfile.py @@ -228,6 +228,7 @@ def test_add_dir_getmember(self): 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) @@ -1018,11 +1019,26 @@ def test_header_offset(self): "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.rstrip('/'))) 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. @@ -1082,6 +1098,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") From 3c1a545e74fde4adcf3b59ca54f995711684ec11 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Fri, 8 Apr 2022 22:12:12 +0000 Subject: [PATCH 2/3] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../NEWS.d/next/Library/2022-04-08-22-12-11.bpo-47231.lvyglt.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2022-04-08-22-12-11.bpo-47231.lvyglt.rst 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 index 00000000000000..ee05c5e2856756 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-04-08-22-12-11.bpo-47231.lvyglt.rst @@ -0,0 +1 @@ +Fixed an issue with inconsistent trailing slashes in tarfile longname directories. From bcfd09a8818c8b5cf2730de9db8adac7b7ebf0ff Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 17 Jun 2022 14:51:12 -0700 Subject: [PATCH 3/3] Apply suggestions from code review --- Lib/tarfile.py | 2 +- Lib/test/test_tarfile.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/tarfile.py b/Lib/tarfile.py index 7a4880565b8891..169c88d63f781b 100755 --- a/Lib/tarfile.py +++ b/Lib/tarfile.py @@ -1193,7 +1193,7 @@ def _proc_gnulong(self, tarfile): # Remove redundant slashes from directories. This is to be consistent # with frombuf(). if next.isdir(): - next.name = next.name.rstrip("/") + next.name = next.name.removesuffix("/") return next diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py index 4a669344ea5149..f1aed5ccc6b76b 100644 --- a/Lib/test/test_tarfile.py +++ b/Lib/test/test_tarfile.py @@ -1034,7 +1034,7 @@ def test_longname_directory(self): os.rmdir(longdir) with tarfile.open(tmpname) as tar: self.assertIsNotNone(tar.getmember(longdir)) - self.assertIsNotNone(tar.getmember(longdir.rstrip('/'))) + self.assertIsNotNone(tar.getmember(longdir.removesuffix('/'))) class GNUReadTest(LongnameTest, ReadTest, unittest.TestCase):