Merged revisions 83959-83960 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/branches/py3k

........
  r83959 | antoine.pitrou | 2010-08-12 17:11:50 +0200 (jeu., 12 août 2010) | 5 lines

  Issue #7467: when a file from a ZIP archive, its CRC is checked and a
  BadZipfile error is raised if it doesn't match (as used to be the
  case in Python 2.5 and earlier).
........
  r83960 | antoine.pitrou | 2010-08-12 17:15:01 +0200 (jeu., 12 août 2010) | 3 lines

  Typo.
........
diff --git a/Lib/zipfile.py b/Lib/zipfile.py
index 79ca152..3d2d57b 100644
--- a/Lib/zipfile.py
+++ b/Lib/zipfile.py
@@ -472,6 +472,12 @@
         if self.compress_type == ZIP_DEFLATED:
             self.dc = zlib.decompressobj(-15)
 
+        if hasattr(zipinfo, 'CRC'):
+            self._expected_crc = zipinfo.CRC
+            self._running_crc = crc32(b'') & 0xffffffff
+        else:
+            self._expected_crc = None
+
     def set_univ_newlines(self, univ_newlines):
         self.univ_newlines = univ_newlines
 
@@ -565,6 +571,16 @@
             result.append(line)
         return result
 
+    def _update_crc(self, newdata, eof):
+        # Update the CRC using the given data.
+        if self._expected_crc is None:
+            # No need to compute the CRC if we don't have a reference value
+            return
+        self._running_crc = crc32(newdata, self._running_crc) & 0xffffffff
+        # Check the CRC if we're at the end of the file
+        if eof and self._running_crc != self._expected_crc:
+            raise BadZipfile("Bad CRC-32 for file %r" % self.name)
+
     def read(self, size = None):
         # act like file obj and return empty string if size is 0
         if size == 0:
@@ -628,9 +644,11 @@
                         # prevent decompressor from being used again
                         self.dc = None
 
+                self._update_crc(newdata, eof=(
+                    self.compress_size == self.bytes_read and
+                    len(self.rawbuffer) == 0))
                 self.readbuffer += newdata
 
-
         # return what the user asked for
         if size is None or len(self.readbuffer) <= size:
             data = self.readbuffer
@@ -1382,7 +1400,9 @@
             print(USAGE)
             sys.exit(1)
         zf = ZipFile(args[1], 'r')
-        zf.testzip()
+        badfile = zf.testzip()
+        if badfile:
+            print("The following enclosed file is corrupted: {!r}".format(badfile))
         print("Done testing")
 
     elif args[0] == '-e':