From: Philipp Gesang Date: Mon, 10 Apr 2017 13:01:56 +0000 (+0200) Subject: throw error on partial header reading stream X-Git-Url: http://developer.intra2net.com/git/?a=commitdiff_plain;h=874b9e82f85e6d22b4256b1963d9dd80c4623222;p=python-delta-tar throw error on partial header reading stream Throw the EOF exception only if the stream ends exactly at an object boundary. Otherwise, when less then sizeof(hdr) bytes are returned from read(), throw InvalidHeader to indicate a malformed file. This keeps EOF a “benign” exception. --- diff --git a/deltatar/crypto.py b/deltatar/crypto.py index 99eaf3a..834b8ac 100755 --- a/deltatar/crypto.py +++ b/deltatar/crypto.py @@ -95,7 +95,7 @@ class EndOfFile (Exception): """Reached EOF.""" remainder = 0 msg = 0 - def __init__ (self, n, msg=None): + def __init__ (self, n=None, msg=None): self.remainder = n self.msg = msg @@ -256,10 +256,11 @@ def hdr_read (data): def hdr_read_stream (instr): data = instr.read(PDTCRYPT_HDR_SIZE) ldata = len (data) - if ldata != PDTCRYPT_HDR_SIZE: - raise EndOfFile (ldata, - "read: expected %d B, received %d B" - % (PDTCRYPT_HDR_SIZE, len (data))) + if ldata == 0: + raise EndOfFile + elif ldata != PDTCRYPT_HDR_SIZE: + raise InvalidHeader ("hdr_read_stream: expected %d B, received %d B" + % (PDTCRYPT_HDR_SIZE, ldata)) return hdr_read (data) diff --git a/deltatar/tarfile.py b/deltatar/tarfile.py index 704ecc6..e6099be 100644 --- a/deltatar/tarfile.py +++ b/deltatar/tarfile.py @@ -767,18 +767,16 @@ class _Stream: self.lasthdr = self.fileobj.tell () try: hdr = crypto.hdr_read_stream (self.fileobj) - except crypto.EndOfFile as exn: - if exn.remainder == 0: - raise EOFHeaderError("end of file header") - raise DecryptionError ("Crypto.hdr_read_stream(): hit EOF " - "reading header %r" % (self.fileobj)) \ - from exn + except crypto.EndOfFile: + return False except crypto.InvalidHeader: raise DecryptionError ("Crypto.hdr_read_stream(): error “%s” " "processing %r" % (hdr, self.fileobj)) \ from exn self.remainder = hdr ["ctsize"] # distance to next header - return self.encryption.next (hdr) + self.encryption.next (hdr) + + return True def _finalize_read_encrypt (self): @@ -914,7 +912,10 @@ class _Stream: if self.encryption is not None: if self.remainder <= 0: # prepare next object - self._init_read_encrypt () + if self._init_read_encrypt () is False: # EOF + buf = None + break # while + # only read up to the end of the encrypted object todo = min (size, self.remainder) buf = self.fileobj.read(todo)