summaryrefslogtreecommitdiffstats
path: root/Lib/tarfile.py
diff options
context:
space:
mode:
authorLars Gustäbel <lars@gustaebel.de>2015-07-06 07:29:41 (GMT)
committerLars Gustäbel <lars@gustaebel.de>2015-07-06 07:29:41 (GMT)
commite12aa62d689f435b9b75cde51e432d997646d5f9 (patch)
treec4d9a6888955dd0a184c55de513d41a871228997 /Lib/tarfile.py
parent53ecc58bd9da21989ae1811f97248b40e028ccd9 (diff)
parent0357268d96d4ff3546cfd89f594a5630a3adf747 (diff)
downloadcpython-e12aa62d689f435b9b75cde51e432d997646d5f9.zip
cpython-e12aa62d689f435b9b75cde51e432d997646d5f9.tar.gz
cpython-e12aa62d689f435b9b75cde51e432d997646d5f9.tar.bz2
Merge with 3.4: Issue #24259: tarfile now raises a ReadError if an archive is truncated inside a data segment.
Diffstat (limited to 'Lib/tarfile.py')
-rwxr-xr-xLib/tarfile.py22
1 files changed, 15 insertions, 7 deletions
diff --git a/Lib/tarfile.py b/Lib/tarfile.py
index d1279d2..ca45126 100755
--- a/Lib/tarfile.py
+++ b/Lib/tarfile.py
@@ -225,7 +225,7 @@ def calc_chksums(buf):
signed_chksum = 256 + sum(struct.unpack_from("148b8x356b", buf))
return unsigned_chksum, signed_chksum
-def copyfileobj(src, dst, length=None):
+def copyfileobj(src, dst, length=None, exception=OSError):
"""Copy length bytes from fileobj src to fileobj dst.
If length is None, copy the entire content.
"""
@@ -240,13 +240,13 @@ def copyfileobj(src, dst, length=None):
for b in range(blocks):
buf = src.read(BUFSIZE)
if len(buf) < BUFSIZE:
- raise OSError("end of file reached")
+ raise exception("unexpected end of data")
dst.write(buf)
if remainder != 0:
buf = src.read(remainder)
if len(buf) < remainder:
- raise OSError("end of file reached")
+ raise exception("unexpected end of data")
dst.write(buf)
return
@@ -690,7 +690,10 @@ class _FileInFile(object):
length = min(size, stop - self.position)
if data:
self.fileobj.seek(offset + (self.position - start))
- buf += self.fileobj.read(length)
+ b = self.fileobj.read(length)
+ if len(b) != length:
+ raise ReadError("unexpected end of data")
+ buf += b
else:
buf += NUL * length
size -= length
@@ -2150,9 +2153,9 @@ class TarFile(object):
if tarinfo.sparse is not None:
for offset, size in tarinfo.sparse:
target.seek(offset)
- copyfileobj(source, target, size)
+ copyfileobj(source, target, size, ReadError)
else:
- copyfileobj(source, target, tarinfo.size)
+ copyfileobj(source, target, tarinfo.size, ReadError)
target.seek(tarinfo.size)
target.truncate()
@@ -2267,8 +2270,13 @@ class TarFile(object):
self.firstmember = None
return m
+ # Advance the file pointer.
+ if self.offset != self.fileobj.tell():
+ self.fileobj.seek(self.offset - 1)
+ if not self.fileobj.read(1):
+ raise ReadError("unexpected end of data")
+
# Read the next block.
- self.fileobj.seek(self.offset)
tarinfo = None
while True:
try: