diff options
author | Lars Gustäbel <lars@gustaebel.de> | 2015-07-06 07:29:41 (GMT) |
---|---|---|
committer | Lars Gustäbel <lars@gustaebel.de> | 2015-07-06 07:29:41 (GMT) |
commit | e12aa62d689f435b9b75cde51e432d997646d5f9 (patch) | |
tree | c4d9a6888955dd0a184c55de513d41a871228997 /Lib/tarfile.py | |
parent | 53ecc58bd9da21989ae1811f97248b40e028ccd9 (diff) | |
parent | 0357268d96d4ff3546cfd89f594a5630a3adf747 (diff) | |
download | cpython-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-x | Lib/tarfile.py | 22 |
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: |