summaryrefslogtreecommitdiff
path: root/Lib/zipfile.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/zipfile.py')
-rw-r--r--Lib/zipfile.py24
1 files changed, 22 insertions, 2 deletions
diff --git a/Lib/zipfile.py b/Lib/zipfile.py
index 79ca1527f9..3d2d57b205 100644
--- a/Lib/zipfile.py
+++ b/Lib/zipfile.py
@@ -472,6 +472,12 @@ class ZipExtFile:
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 @@ class ZipExtFile:
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 @@ class ZipExtFile:
# 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 @@ def main(args = None):
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':