summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorLars Gustäbel <lars@gustaebel.de>2008-02-11 18:36:07 (GMT)
committerLars Gustäbel <lars@gustaebel.de>2008-02-11 18:36:07 (GMT)
commit08303dbd722f379e17682daaaf60ad515e1800fb (patch)
treeb2690f937e86cfe99d1a611aeebad5413cf2c7f9 /Lib
parent5ca1cba2523645b6043adf5c59bb448b8d22d816 (diff)
downloadcpython-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.py25
-rw-r--r--Lib/test/test_tarfile.py8
-rw-r--r--Lib/test/testtar.tarbin133120 -> 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
index 1f4493f..6c3efa9 100644
--- a/Lib/test/testtar.tar
+++ b/Lib/test/testtar.tar
Binary files differ