summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeal Norwitz <nnorwitz@gmail.com>2005-10-28 05:52:22 (GMT)
committerNeal Norwitz <nnorwitz@gmail.com>2005-10-28 05:52:22 (GMT)
commitf3396542806e9c6d1dfafda5d1e53296d3d1af09 (patch)
tree20ddb14f9ad9bfeb9c00cf5eb89f31ee23543259
parent466e5b336ea68293abbda84c3e99d64708043443 (diff)
downloadcpython-f3396542806e9c6d1dfafda5d1e53296d3d1af09.zip
cpython-f3396542806e9c6d1dfafda5d1e53296d3d1af09.tar.gz
cpython-f3396542806e9c6d1dfafda5d1e53296d3d1af09.tar.bz2
Patch #1338314, Bug #1336623: fix tarfile so it can extract
REGTYPE directories from tarfiles written by old programs. Will backport.
-rw-r--r--Lib/tarfile.py11
-rw-r--r--Lib/test/test_tarfile.py30
-rw-r--r--Misc/NEWS3
3 files changed, 39 insertions, 5 deletions
diff --git a/Lib/tarfile.py b/Lib/tarfile.py
index c86248c..0b3d477 100644
--- a/Lib/tarfile.py
+++ b/Lib/tarfile.py
@@ -739,6 +739,11 @@ class TarInfo(object):
tarinfo.devmajor = tarinfo.devmajor = 0
tarinfo.prefix = buf[345:500]
+ # Some old tar programs represent a directory as a regular
+ # file with a trailing slash.
+ if tarinfo.isreg() and tarinfo.name.endswith("/"):
+ tarinfo.type = DIRTYPE
+
# The prefix field is used for filenames > 100 in
# the POSIX standard.
# name = prefix + '/' + name
@@ -746,7 +751,7 @@ class TarInfo(object):
tarinfo.name = normpath(os.path.join(nts(tarinfo.prefix), tarinfo.name))
# Directory names should have a '/' at the end.
- if tarinfo.isdir() and tarinfo.name[-1:] != "/":
+ if tarinfo.isdir():
tarinfo.name += "/"
return tarinfo
@@ -1716,10 +1721,6 @@ class TarFile(object):
# Skip the following data blocks.
self.offset += self._block(tarinfo.size)
- if tarinfo.isreg() and tarinfo.name[:-1] == "/":
- # some old tar programs don't know DIRTYPE
- tarinfo.type = DIRTYPE
-
self.members.append(tarinfo)
return tarinfo
diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py
index b202ea5..98349c4 100644
--- a/Lib/test/test_tarfile.py
+++ b/Lib/test/test_tarfile.py
@@ -144,6 +144,36 @@ class ReadTest(BaseTest):
"readlines() after seek failed")
fobj.close()
+ def test_old_dirtype(self):
+ """Test old style dirtype member (bug #1336623).
+ """
+ # Old tars create directory members using a REGTYPE
+ # header with a "/" appended to the filename field.
+
+ # Create an old tar style directory entry.
+ filename = tmpname()
+ tarinfo = tarfile.TarInfo("directory/")
+ tarinfo.type = tarfile.REGTYPE
+
+ fobj = file(filename, "w")
+ fobj.write(tarinfo.tobuf())
+ fobj.close()
+
+ try:
+ # Test if it is still a directory entry when
+ # read back.
+ tar = tarfile.open(filename)
+ tarinfo = tar.getmembers()[0]
+ tar.close()
+
+ self.assert_(tarinfo.type == tarfile.DIRTYPE)
+ self.assert_(tarinfo.name.endswith("/"))
+ finally:
+ try:
+ os.unlink(filename)
+ except:
+ pass
+
class ReadStreamTest(ReadTest):
sep = "|"
diff --git a/Misc/NEWS b/Misc/NEWS
index 8ee1e35..e88311f 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -177,6 +177,9 @@ Core and builtins
Extension Modules
-----------------
+- Patch #1338314, Bug #1336623: fix tarfile so it can extract
+ REGTYPE directories from tarfiles written by old programs.
+
- Get bsddb module to build with BSD DB version 3.2
- Patch #1309009, Fix segfault in pyexpat when the XML document is in latin_1,