[Python-checkins] r61813 - python/trunk/Lib/gzip.py

gregory.p.smith python-checkins at python.org
Sun Mar 23 22:04:43 CET 2008


Author: gregory.p.smith
Date: Sun Mar 23 22:04:43 2008
New Revision: 61813

Modified:
   python/trunk/Lib/gzip.py
Log:
Fix gzip to deal with CRC's being signed values in Python 2.x properly and to
read 32bit values as unsigned to start with rather than applying signedness
fixups allover the place afterwards.

This hopefully fixes the test_tarfile failure on the alpha/tru64 buildbot.


Modified: python/trunk/Lib/gzip.py
==============================================================================
--- python/trunk/Lib/gzip.py	(original)
+++ python/trunk/Lib/gzip.py	Sun Mar 23 22:04:43 2008
@@ -16,28 +16,16 @@
 READ, WRITE = 1, 2
 
 def U32(i):
-    """Return i as an unsigned integer, assuming it fits in 32 bits.
-
-    If it's >= 2GB when viewed as a 32-bit unsigned int, return a long.
-    """
-    if i < 0:
-        i += 1L << 32
-    return i
-
-def LOWU32(i):
-    """Return the low-order 32 bits of an int, as a non-negative int."""
+    """Return the low-order 32 bits, as a non-negative int or long."""
     return i & 0xFFFFFFFFL
 
-def write32(output, value):
-    output.write(struct.pack("<l", value))
-
 def write32u(output, value):
     # The L format writes the bit pattern correctly whether signed
     # or unsigned.
     output.write(struct.pack("<L", value))
 
 def read32(input):
-    return struct.unpack("<l", input.read(4))[0]
+    return struct.unpack("<I", input.read(4))[0]
 
 def open(filename, mode="rb", compresslevel=9):
     """Shorthand for GzipFile(filename, mode, compresslevel).
@@ -141,7 +129,7 @@
 
     def _init_write(self, filename):
         self.name = filename
-        self.crc = zlib.crc32("")
+        self.crc = zlib.crc32("") & 0xffffffffL
         self.size = 0
         self.writebuf = []
         self.bufsize = 0
@@ -163,7 +151,7 @@
             self.fileobj.write(fname + '\000')
 
     def _init_read(self):
-        self.crc = zlib.crc32("")
+        self.crc = zlib.crc32("") & 0xffffffffL
         self.size = 0
 
     def _read_gzip_header(self):
@@ -209,7 +197,7 @@
             raise ValueError, "write() on closed GzipFile object"
         if len(data) > 0:
             self.size = self.size + len(data)
-            self.crc = zlib.crc32(data, self.crc)
+            self.crc = zlib.crc32(data, self.crc) & 0xffffffffL
             self.fileobj.write( self.compress.compress(data) )
             self.offset += len(data)
 
@@ -301,7 +289,7 @@
             self._new_member = True
 
     def _add_read_data(self, data):
-        self.crc = zlib.crc32(data, self.crc)
+        self.crc = zlib.crc32(data, self.crc) & 0xffffffffL
         self.extrabuf = self.extrabuf + data
         self.extrasize = self.extrasize + len(data)
         self.size = self.size + len(data)
@@ -314,25 +302,19 @@
         # stored is the true file size mod 2**32.
         self.fileobj.seek(-8, 1)
         crc32 = read32(self.fileobj)
-        isize = U32(read32(self.fileobj))   # may exceed 2GB
-        if U32(crc32) != U32(self.crc):
-            raise IOError("CRC check failed %s != %s" % (hex(U32(crc32)),
-                                                         hex(U32(self.crc))))
-        elif isize != LOWU32(self.size):
+        isize = read32(self.fileobj)  # may exceed 2GB
+        if crc32 != self.crc:
+            raise IOError("CRC check failed %s != %s" % (hex(crc32),
+                                                         hex(self.crc)))
+        elif isize != self.size:
             raise IOError, "Incorrect length of data produced"
 
     def close(self):
         if self.mode == WRITE:
             self.fileobj.write(self.compress.flush())
-            # The native zlib crc is an unsigned 32-bit integer, but
-            # the Python wrapper implicitly casts that to a signed C
-            # long.  So, on a 32-bit box self.crc may "look negative",
-            # while the same crc on a 64-bit box may "look positive".
-            # To avoid irksome warnings from the `struct` module, force
-            # it to look positive on all boxes.
-            write32u(self.fileobj, LOWU32(self.crc))
+            write32u(self.fileobj, self.crc)
             # self.size may exceed 2GB, or even 4GB
-            write32u(self.fileobj, LOWU32(self.size))
+            write32u(self.fileobj, self.size)
             self.fileobj = None
         elif self.mode == READ:
             self.fileobj = None


More information about the Python-checkins mailing list