@@ -50,7 +50,7 @@ class LargeZipFile(Exception):
5050
5151
5252ZIP64_LIMIT = (1 << 31 ) - 1
53- ZIP_FILECOUNT_LIMIT = 1 << 16
53+ ZIP_FILECOUNT_LIMIT = ( 1 << 16 ) - 1
5454ZIP_MAX_COMMENT = (1 << 16 ) - 1
5555
5656# constants for Zip file compression methods
@@ -1304,13 +1304,17 @@ def _writecheck(self, zinfo):
13041304 raise RuntimeError (
13051305 "Attempt to write ZIP archive that was already closed" )
13061306 _check_compression (zinfo .compress_type )
1307- if zinfo .file_size > ZIP64_LIMIT :
1308- if not self ._allowZip64 :
1309- raise LargeZipFile ("Filesize would require ZIP64 extensions" )
1310- if zinfo .header_offset > ZIP64_LIMIT :
1311- if not self ._allowZip64 :
1312- raise LargeZipFile (
1313- "Zipfile size would require ZIP64 extensions" )
1307+ if not self ._allowZip64 :
1308+ requires_zip64 = None
1309+ if len (self .filelist ) >= ZIP_FILECOUNT_LIMIT :
1310+ requires_zip64 = "Files count"
1311+ elif zinfo .file_size > ZIP64_LIMIT :
1312+ requires_zip64 = "Filesize"
1313+ elif zinfo .header_offset > ZIP64_LIMIT :
1314+ requires_zip64 = "Zipfile size"
1315+ if requires_zip64 :
1316+ raise LargeZipFile (requires_zip64 +
1317+ " would require ZIP64 extensions" )
13141318
13151319 def write (self , filename , arcname = None , compress_type = None ):
13161320 """Put the bytes from filename into the archive under the name
@@ -1464,10 +1468,8 @@ def close(self):
14641468
14651469 try :
14661470 if self .mode in ("w" , "a" ) and self ._didModify : # write ending records
1467- count = 0
14681471 pos1 = self .fp .tell ()
14691472 for zinfo in self .filelist : # write central directory
1470- count = count + 1
14711473 dt = zinfo .date_time
14721474 dosdate = (dt [0 ] - 1980 ) << 9 | dt [1 ] << 5 | dt [2 ]
14731475 dostime = dt [3 ] << 11 | dt [4 ] << 5 | (dt [5 ] // 2 )
@@ -1531,13 +1533,21 @@ def close(self):
15311533
15321534 pos2 = self .fp .tell ()
15331535 # Write end-of-zip-archive record
1534- centDirCount = count
1536+ centDirCount = len ( self . filelist )
15351537 centDirSize = pos2 - pos1
15361538 centDirOffset = pos1
1537- if (centDirCount >= ZIP_FILECOUNT_LIMIT or
1538- centDirOffset > ZIP64_LIMIT or
1539- centDirSize > ZIP64_LIMIT ):
1539+ requires_zip64 = None
1540+ if centDirCount > ZIP_FILECOUNT_LIMIT :
1541+ requires_zip64 = "Files count"
1542+ elif centDirOffset > ZIP64_LIMIT :
1543+ requires_zip64 = "Central directory offset"
1544+ elif centDirSize > ZIP64_LIMIT :
1545+ requires_zip64 = "Central directory size"
1546+ if requires_zip64 :
15401547 # Need to write the ZIP64 end-of-archive records
1548+ if not self ._allowZip64 :
1549+ raise LargeZipFile (requires_zip64 +
1550+ " would require ZIP64 extensions" )
15411551 zip64endrec = struct .pack (
15421552 structEndArchive64 , stringEndArchive64 ,
15431553 44 , 45 , 45 , 0 , 0 , centDirCount , centDirCount ,
0 commit comments