diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2013-01-31 13:27:07 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2013-01-31 13:27:07 (GMT) |
commit | d2b1527f1418f4bac9d05933623ef1a9d1948f61 (patch) | |
tree | edf98076cc77cb2f10c05129e9225bacb6a991d6 /Lib/zipfile.py | |
parent | fc20d77b408937723e9105f0d5a55d322a8d6853 (diff) | |
download | cpython-d2b1527f1418f4bac9d05933623ef1a9d1948f61.zip cpython-d2b1527f1418f4bac9d05933623ef1a9d1948f61.tar.gz cpython-d2b1527f1418f4bac9d05933623ef1a9d1948f61.tar.bz2 |
Issue #4844: ZipFile now raises BadZipFile when opens a ZIP file with an
incomplete "End of Central Directory" record. Original patch by Guilherme
Polo and Alan McIntyre.
Diffstat (limited to 'Lib/zipfile.py')
-rw-r--r-- | Lib/zipfile.py | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/Lib/zipfile.py b/Lib/zipfile.py index a7cee72..f900abd 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -176,6 +176,8 @@ def _EndRecData64(fpin, offset, endrec): return endrec data = fpin.read(sizeEndCentDir64Locator) + if len(data) != sizeEndCentDir64Locator: + return endrec sig, diskno, reloff, disks = struct.unpack(structEndArchive64Locator, data) if sig != stringEndArchive64Locator: return endrec @@ -186,6 +188,8 @@ def _EndRecData64(fpin, offset, endrec): # Assume no 'zip64 extensible data' fpin.seek(offset - sizeEndCentDir64Locator - sizeEndCentDir64, 2) data = fpin.read(sizeEndCentDir64) + if len(data) != sizeEndCentDir64: + return endrec sig, sz, create_version, read_version, disk_num, disk_dir, \ dircount, dircount2, dirsize, diroffset = \ struct.unpack(structEndArchive64, data) @@ -221,7 +225,9 @@ def _EndRecData(fpin): except IOError: return None data = fpin.read() - if data[0:4] == stringEndArchive and data[-2:] == b"\000\000": + if (len(data) == sizeEndCentDir and + data[0:4] == stringEndArchive and + data[-2:] == b"\000\000"): # the signature is correct and there's no comment, unpack structure endrec = struct.unpack(structEndArchive, data) endrec=list(endrec) @@ -245,6 +251,9 @@ def _EndRecData(fpin): if start >= 0: # found the magic number; attempt to unpack and interpret recData = data[start:start+sizeEndCentDir] + if len(recData) != sizeEndCentDir: + # Zip file is corrupted. + return None endrec = list(struct.unpack(structEndArchive, recData)) commentSize = endrec[_ECD_COMMENT_SIZE] #as claimed by the zip file comment = data[start+sizeEndCentDir:start+sizeEndCentDir+commentSize] @@ -256,7 +265,7 @@ def _EndRecData(fpin): endrec) # Unable to find a valid end of central directory structure - return + return None class ZipInfo (object): @@ -819,9 +828,11 @@ class ZipFile: total = 0 while total < size_cd: centdir = fp.read(sizeCentralDir) - if centdir[0:4] != stringCentralDir: - raise BadZipFile("Bad magic number for central directory") + if len(centdir) != sizeCentralDir: + raise BadZipFile("Truncated central directory") centdir = struct.unpack(structCentralDir, centdir) + if centdir[_CD_SIGNATURE] != stringCentralDir: + raise BadZipFile("Bad magic number for central directory") if self.debug > 2: print(centdir) filename = fp.read(centdir[_CD_FILENAME_LENGTH]) @@ -964,10 +975,12 @@ class ZipFile: # Skip the file header: fheader = zef_file.read(sizeFileHeader) - if fheader[0:4] != stringFileHeader: + if len(fheader) != sizeFileHeader: + raise BadZipFile("Truncated file header") + fheader = struct.unpack(structFileHeader, fheader) + if fheader[_FH_SIGNATURE] != stringFileHeader: raise BadZipFile("Bad magic number for file header") - fheader = struct.unpack(structFileHeader, fheader) fname = zef_file.read(fheader[_FH_FILENAME_LENGTH]) if fheader[_FH_EXTRA_FIELD_LENGTH]: zef_file.read(fheader[_FH_EXTRA_FIELD_LENGTH]) |