From ae3d0f2af5b4594ab3ea7820cd52212c83375cbb Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Mon, 10 Apr 2017 13:43:53 +0200 Subject: [PATCH] communicate remainder to caller when hitting EOF from crypto --- deltatar/crypto.py | 18 +++++++++++++----- deltatar/tarfile.py | 16 ++++++++++------ 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/deltatar/crypto.py b/deltatar/crypto.py index bcc89b8..99eaf3a 100755 --- a/deltatar/crypto.py +++ b/deltatar/crypto.py @@ -93,7 +93,11 @@ __all__ = [ "hdr_make", "hdr_read", "hdr_fmt", "hdr_fmt_pretty" class EndOfFile (Exception): """Reached EOF.""" - pass + remainder = 0 + msg = 0 + def __init__ (self, n, msg=None): + self.remainder = n + self.msg = msg class InvalidParameter (Exception): @@ -251,8 +255,10 @@ def hdr_read (data): def hdr_read_stream (instr): data = instr.read(PDTCRYPT_HDR_SIZE) - if len (data) != PDTCRYPT_HDR_SIZE: - raise EndOfFile ("read: expected %d B, received %d B" + ldata = len (data) + if ldata != PDTCRYPT_HDR_SIZE: + raise EndOfFile (ldata, + "read: expected %d B, received %d B" % (PDTCRYPT_HDR_SIZE, len (data))) return hdr_read (data) @@ -772,7 +778,8 @@ def depdtcrypt (pw, ins, outs): try: hdr = hdr_read_stream (ins) total_read += PDTCRYPT_HDR_SIZE - except EndOfFile: + except EndOfFile as exn: + total_read += exn.remainder if total_ct + total_obj * PDTCRYPT_HDR_SIZE != total_read: raise PDTDecryptionError ("ciphertext processed (%d B) plus " "overhead (%d × %d B) does not match " @@ -808,7 +815,8 @@ def depdtcrypt (pw, ins, outs): nct = len (ct) if nct < nexpect: off = tell (ins) - raise EndOfFile ("hit EOF after %d of %d B in block [%d:%d); " + raise EndOfFile (nct, + "hit EOF after %d of %d B in block [%d:%d); " "%d B ciphertext remaining for object no %d" % (nct, nexpect, off, off + nexpect, ctleft, total_obj)) diff --git a/deltatar/tarfile.py b/deltatar/tarfile.py index 23968fc..704ecc6 100644 --- a/deltatar/tarfile.py +++ b/deltatar/tarfile.py @@ -707,7 +707,9 @@ class _Stream: self.__enc_write(self.buf) if close_fileobj is True: - fixed = self._finalize_write_encrypt () + if self.mode == "w": + # end of Tar archive marker (two empty blocks) was written + fixed = self._finalize_write_encrypt () if not self._extfileobj: self.fileobj.close() else: @@ -765,12 +767,16 @@ class _Stream: self.lasthdr = self.fileobj.tell () try: hdr = crypto.hdr_read_stream (self.fileobj) - except crypto.EndOfFile: + 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)) + "reading header %r" % (self.fileobj)) \ + from exn except crypto.InvalidHeader: raise DecryptionError ("Crypto.hdr_read_stream(): error “%s” " - "processing %r" % (hdr, self.fileobj)) + "processing %r" % (hdr, self.fileobj)) \ + from exn self.remainder = hdr ["ctsize"] # distance to next header return self.encryption.next (hdr) @@ -903,9 +909,7 @@ class _Stream: """ c = len(self.buf) t = [self.buf] - i = 0 while c < size: - i += 1 todo = size if self.encryption is not None: if self.remainder <= 0: -- 1.7.1