https://github.com/python/cpython/commit/9288ef75c148376a5f039fc7621019dffac75259 commit: 9288ef75c148376a5f039fc7621019dffac75259 branch: 3.14 author: Miss Islington (bot) <[email protected]> committer: hugovk <[email protected]> date: 2026-10-23T20:36:29+03:00 summary:
[3.14] gh-127636: Fix tarfile extracting trailing slash member names (GH-152984) (#157168) Co-authored-by: Xiao Yuan <[email protected]> files: A Misc/NEWS.d/next/Library/2026-07-04-00-19-23.gh-issue-127636.o_uD9U.rst M Lib/tarfile.py M Lib/test/test_tarfile.py diff --git a/Lib/tarfile.py b/Lib/tarfile.py index 1ee2f77c0ab22e..8d88d94fc423fb 100644 --- a/Lib/tarfile.py +++ b/Lib/tarfile.py @@ -2195,7 +2195,9 @@ def getmember(self, name): than once in the archive, its last occurrence is assumed to be the most up-to-date version. """ - tarinfo = self._getmember(name.rstrip('/')) + tarinfo = self._getmember(name) + if tarinfo is None and name.endswith('/'): + tarinfo = self._getmember(name.rstrip('/')) if tarinfo is None: raise KeyError("filename %r not found" % name) return tarinfo diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py index 5cb9a2300a3e03..8002c303246793 100644 --- a/Lib/test/test_tarfile.py +++ b/Lib/test/test_tarfile.py @@ -254,6 +254,19 @@ def test_add_dir_getmember(self): self.add_dir_and_getmember('bar') self.add_dir_and_getmember('a'*101) + def test_extract_name_with_trailing_slash(self): + # gh-127636: './mydir/' is deliberately a regular-file member + # (REGTYPE, not DIRTYPE) whose stored name ends in a slash. It + # extracts as a file. Do not "fix" this by setting DIRTYPE; the + # trailing-slash name on a non-directory is what is being tested. + with tarfile.open(tmpname, 'w') as tar: + tar.addfile(tarfile.TarInfo('./mydir/')) + with os_helper.temp_dir() as tmpdir, tarfile.open(tmpname) as tar: + names = tar.getnames() + self.assertEqual(names, ['./mydir/']) + tar.extract(names[0], tmpdir, filter='fully_trusted') + self.assertTrue(os.path.isfile(os.path.join(tmpdir, 'mydir'))) + @unittest.skipUnless(hasattr(os, "getuid") and hasattr(os, "getgid"), "Missing getuid or getgid implementation") def add_dir_and_getmember(self, name): diff --git a/Misc/NEWS.d/next/Library/2026-07-04-00-19-23.gh-issue-127636.o_uD9U.rst b/Misc/NEWS.d/next/Library/2026-07-04-00-19-23.gh-issue-127636.o_uD9U.rst new file mode 100644 index 00000000000000..51957a73b5603b --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-07-04-00-19-23.gh-issue-127636.o_uD9U.rst @@ -0,0 +1,3 @@ +Fix :meth:`tarfile.TarFile.extract` to accept archive member names with a +trailing forward slash, including those returned by +:meth:`tarfile.TarFile.getnames`. Contributed by Xiao Yuan. _______________________________________________ Python-checkins mailing list -- [email protected] To unsubscribe send an email to [email protected] https://mail.python.org/mailman3//lists/python-checkins.python.org Member address: [email protected]
