adding crc checking when reading tar.gz files
authorEduardo Robles Elvira <edulix@wadobo.com>
Tue, 9 Jul 2013 14:14:14 +0000 (16:14 +0200)
committerEduardo Robles Elvira <edulix@wadobo.com>
Wed, 10 Jul 2013 11:00:21 +0000 (13:00 +0200)
deltatar/tarfile.py

index df44b2f..dc9554e 100644 (file)
@@ -430,11 +430,11 @@ class _Stream:
             except ImportError:
                 raise CompressionError("zlib module is not available")
             self.zlib = zlib
-            self.crc = zlib.crc32("") & 0xffffffffL
             if mode == "r":
                 self._init_read_gz()
             else:
                 self._init_write_gz()
+            self.crc = zlib.crc32("") & 0xffffffffL
 
         if comptype == "bz2":
             try:
@@ -481,11 +481,10 @@ class _Stream:
         '''
         Add a new gzip block, closing last one
         '''
-        import zlib
         self.close(close_fileobj=False)
         self.closed = False
         self.concat_pos = 0L
-        self.crc = zlib.crc32("") & 0xffffffffL
+        self.crc = self.zlib.crc32("") & 0xffffffffL
         self.cmp = self.zlib.compressobj(9, self.zlib.DEFLATED,
                                             -self.zlib.MAX_WBITS,
                                             self.zlib.DEF_MEM_LEVEL,
@@ -539,9 +538,13 @@ class _Stream:
         if close_fileobj and not self._extfileobj:
             self.fileobj.close()
 
-        # read the zlib crc
-        if not close_fileobj and self.mode == "r":
-            self.__read(8)
+        # read the zlib crc and length and check them
+        if not close_fileobj and self.mode == "r" and self.comptype == "gz":
+            read_crc = self.__read(4)
+            read_length = self.__read(4)
+            calculated_crc = self.crc & 0xffffffffL
+            if struct.unpack("<L", read_crc)[0] != calculated_crc:
+                raise CompressionError("bad gzip crc")
 
         self.closed = True
 
@@ -632,15 +635,18 @@ class _Stream:
             except IOError:
                 raise ReadError("invalid compressed data")
 
+            if self.comptype == "gz" and hasattr(self, "crc"):
+                self.crc = self.zlib.crc32(buf, self.crc) & 0xffffffffL
             if self.concat_stream and len(self.cmp.unused_data) != 0:
                 self.buf = self.cmp.unused_data + self.buf
                 self.close(close_fileobj=False)
                 try:
                     self._init_read_gz()
-                    self.closed = False
                 except:
                     # happens at the end of the file
                     pass
+                self.crc = self.zlib.crc32("") & 0xffffffffL
+                self.closed = False
             t.append(buf)
             c += len(buf)
         t = "".join(t)