diff options
| author | Lars Gustäbel <lars@gustaebel.de> | 2008-02-11 18:36:07 (GMT) |
|---|---|---|
| committer | Lars Gustäbel <lars@gustaebel.de> | 2008-02-11 18:36:07 (GMT) |
| commit | 08303dbd722f379e17682daaaf60ad515e1800fb (patch) | |
| tree | b2690f937e86cfe99d1a611aeebad5413cf2c7f9 /Lib | |
| parent | 5ca1cba2523645b6043adf5c59bb448b8d22d816 (diff) | |
| download | cpython-08303dbd722f379e17682daaaf60ad515e1800fb.zip cpython-08303dbd722f379e17682daaaf60ad515e1800fb.tar.gz cpython-08303dbd722f379e17682daaaf60ad515e1800fb.tar.bz2 | |
Backport the nts() function from the trunk. This fixes problems with
the xstar format that puts extra fields inside the space that POSIX
has reserved for the prefix field.
Diffstat (limited to 'Lib')
| -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 |
3 files changed, 24 insertions, 9 deletions
diff --git a/Lib/tarfile.py b/Lib/tarfile.py index 94fdcb0..5ad096d 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 dc28038..a9797ae 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 1f4493f..6c3efa9 100644 --- a/Lib/test/testtar.tar +++ b/Lib/test/testtar.tar |
