diff options
-rw-r--r-- | Lib/tarfile.py | 25 | ||||
-rw-r--r-- | Lib/test/test_tarfile.py | 8 | ||||
-rw-r--r-- | Lib/test/testtar.tar | bin | 133120 -> 143360 bytes | |||
-rw-r--r-- | Misc/NEWS | 2 |
4 files changed, 26 insertions, 9 deletions
diff --git a/Lib/tarfile.py b/Lib/tarfile.py index 94fdcb0276..5ad096dbf3 100644 --- a/Lib/tarfile.py +++ b/Lib/tarfile.py @@ -139,13 +139,22 @@ def stn(s, length): """ return s[:length] + (length - len(s)) * NUL +def nts(s): + """Convert a null-terminated string field to a python string. + """ + # Use the string up to the first null char. + p = s.find("\0") + if p == -1: + return s + return s[:p] + def nti(s): """Convert a number field to a python number. """ # There are two possible encodings for a number field, see # itn() below. if s[0] != chr(0200): - n = int(s.rstrip(NUL + " ") or "0", 8) + n = int(nts(s) or "0", 8) else: n = 0L for i in xrange(len(s) - 1): @@ -872,7 +881,7 @@ class TarInfo(object): tarinfo = cls() tarinfo.buf = buf - tarinfo.name = buf[0:100].rstrip(NUL) + tarinfo.name = nts(buf[0:100]) tarinfo.mode = nti(buf[100:108]) tarinfo.uid = nti(buf[108:116]) tarinfo.gid = nti(buf[116:124]) @@ -880,12 +889,12 @@ class TarInfo(object): tarinfo.mtime = nti(buf[136:148]) tarinfo.chksum = nti(buf[148:156]) tarinfo.type = buf[156:157] - tarinfo.linkname = buf[157:257].rstrip(NUL) - tarinfo.uname = buf[265:297].rstrip(NUL) - tarinfo.gname = buf[297:329].rstrip(NUL) + tarinfo.linkname = nts(buf[157:257]) + tarinfo.uname = nts(buf[265:297]) + tarinfo.gname = nts(buf[297:329]) tarinfo.devmajor = nti(buf[329:337]) tarinfo.devminor = nti(buf[337:345]) - prefix = buf[345:500].rstrip(NUL) + prefix = nts(buf[345:500]) if prefix and not tarinfo.issparse(): tarinfo.name = prefix + "/" + tarinfo.name @@ -1892,9 +1901,9 @@ class TarFile(object): # the longname information. next.offset = tarinfo.offset if tarinfo.type == GNUTYPE_LONGNAME: - next.name = buf.rstrip(NUL) + next.name = nts(buf) elif tarinfo.type == GNUTYPE_LONGLINK: - next.linkname = buf.rstrip(NUL) + next.linkname = nts(buf) return next diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py index dc2803895d..a9797aeb99 100644 --- a/Lib/test/test_tarfile.py +++ b/Lib/test/test_tarfile.py @@ -26,7 +26,7 @@ def path(path): testtar = path("testtar.tar") tempdir = os.path.join(tempfile.gettempdir(), "testtar" + os.extsep + "dir") tempname = test_support.TESTFN -membercount = 12 +membercount = 13 def tarname(comp=""): if not comp: @@ -225,6 +225,12 @@ class ReadTest(BaseTest): self.assertEqual(tarinfo.mtime, os.path.getmtime(path)) tar.close() + def test_star(self): + try: + self.tar.getmember("7-STAR") + except KeyError: + self.fail("finding 7-STAR member failed (mangled prefix?)") + class ReadStreamTest(ReadTest): sep = "|" diff --git a/Lib/test/testtar.tar b/Lib/test/testtar.tar Binary files differindex 1f4493f351..6c3efa9b01 100644 --- a/Lib/test/testtar.tar +++ b/Lib/test/testtar.tar @@ -83,6 +83,8 @@ Core and builtins Library ------- +- tarfile.py: Fix reading of xstar archives. + - #2021: Allow tempfile.NamedTemporaryFile to be used in with statements by correctly supporting the context management protocol. |