Skip to content

Commit

Permalink
gh-91387: Strip trailing slash from tarfile longname directories (GH-…
Browse files Browse the repository at this point in the history
…32423)

Co-authored-by: Brett Cannon <brett@python.org>
  • Loading branch information
cfernald and brettcannon authored Jun 17, 2022
1 parent b1ae4af commit c1e1942
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 0 deletions.
10 changes: 10 additions & 0 deletions Lib/tarfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand All @@ -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.removesuffix("/")

return next

def _proc_sparse(self, tarfile):
Expand Down
17 changes: 17 additions & 0 deletions Lib/test/test_tarfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -1020,11 +1021,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.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.
Expand Down Expand Up @@ -1084,6 +1100,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")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fixed an issue with inconsistent trailing slashes in tarfile longname directories.

0 comments on commit c1e1942

Please sign in to comment.