From: Philipp Gesang Date: Fri, 11 Aug 2017 08:25:12 +0000 (+0200) Subject: sync tarfile stream diligently when writing new objects X-Git-Tag: v2.2~7^2~82 X-Git-Url: http://developer.intra2net.com/git/?a=commitdiff_plain;h=0349168a809b5ea0a2082325de34a3cdb5899d0c;p=python-delta-tar sync tarfile stream diligently when writing new objects Turns out all the offsets written to the index when neither encrypting nor compressing were, well, … off. In fact they would only be updated at tar block boundaries due to buffering. Since “last_block_offset” record keeping blatantly violates layering boundaries, it would only work reliably with the concat compression and encryption modes that do the same. Sync when adding a new object so we get the accurate offset value. Voilà, recovery now works with uncompressed and unencrypted archives as well --- diff --git a/deltatar/deltatar.py b/deltatar/deltatar.py index b247fdb..1b15a0a 100644 --- a/deltatar/deltatar.py +++ b/deltatar/deltatar.py @@ -1031,7 +1031,7 @@ class DeltaTar(object): self.f = None def __next__(self): - # read each file in the index and process it to do the retore + # read each file in the index and process it to do the restore j = {} l_no = -1 try: diff --git a/deltatar/tarfile.py b/deltatar/tarfile.py index d67b4fd..49678cc 100644 --- a/deltatar/tarfile.py +++ b/deltatar/tarfile.py @@ -592,13 +592,15 @@ class _Stream: if self.arcmode & ARCMODE_COMPRESS: if getattr (self, "cmp", None) is not None: self._finalize_write_gz () + self.__sync() + if self.arcmode & ~(ARCMODE_ENCRYPT | ARCMODE_COMPRESS): + self.last_block_offset = self.fileobj.tell() if self.arcmode & ARCMODE_ENCRYPT: - self.__sync () self._finalize_write_encrypt () self._init_write_encrypt (name, set_last_block_offset=True) if self.arcmode & ARCMODE_COMPRESS: self._init_write_gz (set_last_block_offset = - not (self.arcmode & ARCMODE_ENCRYPT)) + not (self.arcmode & ARCMODE_ENCRYPT)) return self.last_block_offset diff --git a/runtests.py b/runtests.py index d1ed888..2ed85cb 100755 --- a/runtests.py +++ b/runtests.py @@ -26,6 +26,7 @@ from testing.test_recover import \ RecoverCorruptPayloadTest \ , RecoverCorruptPayloadGZTest \ , RecoverCorruptPayloadGZAESTest \ + , RecoverCorruptHeaderTest \ , RecoverCorruptHeaderGZTest \ , RecoverCorruptHeaderGZAESTest from testing.test_rescue_tar import RescueTarTest @@ -65,6 +66,7 @@ if __name__ == "__main__": , RecoverCorruptPayloadTest , RecoverCorruptPayloadGZTest , RecoverCorruptPayloadGZAESTest + , RecoverCorruptHeaderTest , RecoverCorruptHeaderGZTest , RecoverCorruptHeaderGZAESTest ]: diff --git a/testing/test_recover.py b/testing/test_recover.py index 5ecfb1f..fd85707 100644 --- a/testing/test_recover.py +++ b/testing/test_recover.py @@ -224,7 +224,7 @@ class RecoverTest (BaseTest): "%s/%s" % (bak_path, index_file) ]) - print ("¤¤¤ failed", failed) + print("¤¤¤ failed", failed) assert len (failed) == self.FAILURES # with one file missing @@ -258,6 +258,13 @@ class RecoverCorruptPayloadGZAESTest (RecoverTest): FAILURES = 1 +class RecoverCorruptHeaderTest (RecoverTest): + COMPRESSION = None + PASSWORD = None + FAILURES = 1 + CORRUPT = corrupt_header + + class RecoverCorruptHeaderGZTest (RecoverTest): COMPRESSION = "#gz" PASSWORD = None