#3997: zipfiles generated with more than 65536 files could not be opened

with other applications.

Reviewed by Martin, will backport to 2.6 and 3.0
This commit is contained in:
Amaury Forgeot d'Arc 2009-01-17 16:40:17 +00:00
parent f320c22701
commit d25f87ae36
2 changed files with 16 additions and 7 deletions

View File

@ -26,7 +26,7 @@ class LargeZipFile(Exception):
error = BadZipfile # The exception raised by this module error = BadZipfile # The exception raised by this module
ZIP64_LIMIT= (1 << 31) - 1 ZIP64_LIMIT = (1 << 31) - 1
ZIP_FILECOUNT_LIMIT = 1 << 16 ZIP_FILECOUNT_LIMIT = 1 << 16
ZIP_MAX_COMMENT = (1 << 16) - 1 ZIP_MAX_COMMENT = (1 << 16) - 1
@ -1187,19 +1187,26 @@ class ZipFile:
pos2 = self.fp.tell() pos2 = self.fp.tell()
# Write end-of-zip-archive record # Write end-of-zip-archive record
centDirCount = count
centDirSize = pos2 - pos1
centDirOffset = pos1 centDirOffset = pos1
if pos1 > ZIP64_LIMIT: if (centDirCount >= ZIP_FILECOUNT_LIMIT or
centDirOffset > ZIP64_LIMIT or
centDirSize > ZIP64_LIMIT):
# Need to write the ZIP64 end-of-archive records # Need to write the ZIP64 end-of-archive records
zip64endrec = struct.pack( zip64endrec = struct.pack(
structEndArchive64, stringEndArchive64, structEndArchive64, stringEndArchive64,
44, 45, 45, 0, 0, count, count, pos2 - pos1, pos1) 44, 45, 45, 0, 0, centDirCount, centDirCount,
centDirSize, centDirOffset)
self.fp.write(zip64endrec) self.fp.write(zip64endrec)
zip64locrec = struct.pack( zip64locrec = struct.pack(
structEndArchive64Locator, structEndArchive64Locator,
stringEndArchive64Locator, 0, pos2, 1) stringEndArchive64Locator, 0, pos2, 1)
self.fp.write(zip64locrec) self.fp.write(zip64locrec)
centDirOffset = 0xFFFFFFFF centDirCount = min(centDirCount, 0xFFFF)
centDirSize = min(centDirSize, 0xFFFFFFFF)
centDirOffset = min(centDirOffset, 0xFFFFFFFF)
# check for valid comment length # check for valid comment length
if len(self.comment) >= ZIP_MAX_COMMENT: if len(self.comment) >= ZIP_MAX_COMMENT:
@ -1209,9 +1216,8 @@ class ZipFile:
self.comment = self.comment[:ZIP_MAX_COMMENT] self.comment = self.comment[:ZIP_MAX_COMMENT]
endrec = struct.pack(structEndArchive, stringEndArchive, endrec = struct.pack(structEndArchive, stringEndArchive,
0, 0, count % ZIP_FILECOUNT_LIMIT, 0, 0, centDirCount, centDirCount,
count % ZIP_FILECOUNT_LIMIT, pos2 - pos1, centDirSize, centDirOffset, len(self.comment))
centDirOffset, len(self.comment))
self.fp.write(endrec) self.fp.write(endrec)
self.fp.write(self.comment) self.fp.write(self.comment)
self.fp.flush() self.fp.flush()

View File

@ -137,6 +137,9 @@ Core and Builtins
Library Library
------- -------
- Issue #3997: zipfiles generated with more than 65536 files could not be
opened with other applications.
- Issue #1162154: inspect.getmembers() now skips attributes that raise - Issue #1162154: inspect.getmembers() now skips attributes that raise
AttributeError, e.g. a __slots__ attribute which has not been set. AttributeError, e.g. a __slots__ attribute which has not been set.