[Python-checkins] r61591 - python/trunk/Lib/zipfile.py

gregory.p.smith python-checkins at python.org
Wed Mar 19 04:14:42 CET 2008


Author: gregory.p.smith
Date: Wed Mar 19 04:14:41 2008
New Revision: 61591

Modified:
   python/trunk/Lib/zipfile.py
Log:
Fix the struct module DeprecationWarnings that zipfile was triggering by
removing all use of signed struct values.

test_zipfile and test_zipfile64 pass.  no more warnings.


Modified: python/trunk/Lib/zipfile.py
==============================================================================
--- python/trunk/Lib/zipfile.py	(original)
+++ python/trunk/Lib/zipfile.py	Wed Mar 19 04:14:41 2008
@@ -36,13 +36,13 @@
 # Here are some struct module formats for reading headers
 structEndArchive = "<4s4H2LH"     # 9 items, end of archive, 22 bytes
 stringEndArchive = "PK\005\006"   # magic number for end of archive record
-structCentralDir = "<4s4B4HlLL5HLL"# 19 items, central directory, 46 bytes
+structCentralDir = "<4s4B4HLLL5HLL"# 19 items, central directory, 46 bytes
 stringCentralDir = "PK\001\002"   # magic number for central directory
-structFileHeader = "<4s2B4HlLL2H"  # 12 items, file header record, 30 bytes
+structFileHeader = "<4s2B4HLLL2H"  # 12 items, file header record, 30 bytes
 stringFileHeader = "PK\003\004"   # magic number for file header
-structEndArchive64Locator = "<4slql" # 4 items, locate Zip64 header, 20 bytes
+structEndArchive64Locator = "<4sLQL" # 4 items, locate Zip64 header, 20 bytes
 stringEndArchive64Locator = "PK\x06\x07" # magic token for locator header
-structEndArchive64 = "<4sqhhllqqqq" # 10 items, end of archive (Zip64), 56 bytes
+structEndArchive64 = "<4sQHHLLQQQQ" # 10 items, end of archive (Zip64), 56 bytes
 stringEndArchive64 = "PK\x06\x06" # magic token for Zip64 header
 
 
@@ -140,7 +140,7 @@
         endrec = list(endrec)
         endrec.append("")               # Append the archive comment
         endrec.append(filesize - 22)    # Append the record start offset
-        if endrec[-4] == -1 or endrec[-4] == 0xffffffff:
+        if endrec[-4] == 0xffffffff:
             return _EndRecData64(fpin, -22, endrec)
         return endrec
     # Search the last END_BLOCK bytes of the file for the record signature.
@@ -160,7 +160,7 @@
             # Append the archive comment and start offset
             endrec.append(comment)
             endrec.append(filesize - END_BLOCK + start)
-            if endrec[-4] == -1 or endrec[-4] == 0xffffffff:
+            if endrec[-4] == 0xffffffff:
                 return _EndRecData64(fpin, - END_BLOCK + start, endrec)
             return endrec
     return      # Error, return None
@@ -247,7 +247,7 @@
         if file_size > ZIP64_LIMIT or compress_size > ZIP64_LIMIT:
             # File is larger than what fits into a 4 byte integer,
             # fall back to the ZIP64 extension
-            fmt = '<hhqq'
+            fmt = '<HHQQ'
             extra = extra + struct.pack(fmt,
                     1, struct.calcsize(fmt)-4, file_size, compress_size)
             file_size = 0xffffffff # -1
@@ -267,14 +267,14 @@
         extra = self.extra
         unpack = struct.unpack
         while extra:
-            tp, ln = unpack('<hh', extra[:4])
+            tp, ln = unpack('<HH', extra[:4])
             if tp == 1:
                 if ln >= 24:
-                    counts = unpack('<qqq', extra[4:28])
+                    counts = unpack('<QQQ', extra[4:28])
                 elif ln == 16:
-                    counts = unpack('<qq', extra[4:20])
+                    counts = unpack('<QQ', extra[4:20])
                 elif ln == 8:
-                    counts = unpack('<q', extra[4:12])
+                    counts = unpack('<Q', extra[4:12])
                 elif ln == 0:
                     counts = ()
                 else:
@@ -283,7 +283,8 @@
                 idx = 0
 
                 # ZIP64 extension (large files and/or large archives)
-                if self.file_size == -1 or self.file_size == 0xFFFFFFFFL:
+                # XXX Is this correct? won't this exclude 2**32-1 byte files?
+                if self.file_size in (0xffffffffffffffffL, 0xffffffffL):
                     self.file_size = counts[idx]
                     idx += 1
 
@@ -942,7 +943,7 @@
             if not buf:
                 break
             file_size = file_size + len(buf)
-            CRC = crc32(buf, CRC)
+            CRC = crc32(buf, CRC) & 0xffffffff
             if cmpr:
                 buf = cmpr.compress(buf)
                 compress_size = compress_size + len(buf)
@@ -960,7 +961,7 @@
         # Seek backwards and write CRC and file sizes
         position = self.fp.tell()       # Preserve current position in file
         self.fp.seek(zinfo.header_offset + 14, 0)
-        self.fp.write(struct.pack("<lLL", zinfo.CRC, zinfo.compress_size,
+        self.fp.write(struct.pack("<LLL", zinfo.CRC, zinfo.compress_size,
               zinfo.file_size))
         self.fp.seek(position, 0)
         self.filelist.append(zinfo)
@@ -985,7 +986,7 @@
         zinfo.header_offset = self.fp.tell()    # Start of header bytes
         self._writecheck(zinfo)
         self._didModify = True
-        zinfo.CRC = crc32(bytes)       # CRC-32 checksum
+        zinfo.CRC = crc32(bytes) & 0xffffffff       # CRC-32 checksum
         if zinfo.compress_type == ZIP_DEFLATED:
             co = zlib.compressobj(zlib.Z_DEFAULT_COMPRESSION,
                  zlib.DEFLATED, -15)
@@ -1035,7 +1036,7 @@
 
                 if zinfo.header_offset > ZIP64_LIMIT:
                     extra.append(zinfo.header_offset)
-                    header_offset = -1  # struct "l" format:  32 one bits
+                    header_offset = 0xffffffffL  # -1 32 bit
                 else:
                     header_offset = zinfo.header_offset
 
@@ -1052,14 +1053,25 @@
                     extract_version = zinfo.extract_version
                     create_version = zinfo.create_version
 
-                centdir = struct.pack(structCentralDir,
-                  stringCentralDir, create_version,
-                  zinfo.create_system, extract_version, zinfo.reserved,
-                  zinfo.flag_bits, zinfo.compress_type, dostime, dosdate,
-                  zinfo.CRC, compress_size, file_size,
-                  len(zinfo.filename), len(extra_data), len(zinfo.comment),
-                  0, zinfo.internal_attr, zinfo.external_attr,
-                  header_offset)
+                try:
+                    centdir = struct.pack(structCentralDir,
+                     stringCentralDir, create_version,
+                     zinfo.create_system, extract_version, zinfo.reserved,
+                     zinfo.flag_bits, zinfo.compress_type, dostime, dosdate,
+                     zinfo.CRC, compress_size, file_size,
+                     len(zinfo.filename), len(extra_data), len(zinfo.comment),
+                     0, zinfo.internal_attr, zinfo.external_attr,
+                     header_offset)
+                except DeprecationWarning:
+                    print >>sys.stderr, (structCentralDir,
+                     stringCentralDir, create_version,
+                     zinfo.create_system, extract_version, zinfo.reserved,
+                     zinfo.flag_bits, zinfo.compress_type, dostime, dosdate,
+                     zinfo.CRC, compress_size, file_size,
+                     len(zinfo.filename), len(extra_data), len(zinfo.comment),
+                     0, zinfo.internal_attr, zinfo.external_attr,
+                     header_offset)
+                    raise
                 self.fp.write(centdir)
                 self.fp.write(zinfo.filename)
                 self.fp.write(extra_data)
@@ -1079,10 +1091,8 @@
                         stringEndArchive64Locator, 0, pos2, 1)
                 self.fp.write(zip64locrec)
 
-                # XXX Why is `pos3` computed next?  It's never referenced.
-                pos3 = self.fp.tell()
                 endrec = struct.pack(structEndArchive, stringEndArchive,
-                            0, 0, count, count, pos2 - pos1, -1, 0)
+                            0, 0, count, count, pos2 - pos1, 0xffffffffL, 0)
                 self.fp.write(endrec)
 
             else:


More information about the Python-checkins mailing list