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.
This commit is contained in:
Lars Gustäbel 2008-02-11 18:36:07 +00:00
parent 5ca1cba252
commit 08303dbd72
4 changed files with 26 additions and 9 deletions

View File

@ -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

View File

@ -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 = "|"

Binary file not shown.

View File

@ -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.