@@ -239,8 +239,9 @@ def _check_zipfile(fp):
239239 if endrec [_ECD_ENTRIES_TOTAL ] == 0 and endrec [_ECD_SIZE ] == 0 and endrec [_ECD_OFFSET ] == 0 :
240240 return True # Empty zipfiles are still zipfiles
241241 elif endrec [_ECD_DISK_NUMBER ] == endrec [_ECD_DISK_START ]:
242- fp .seek (endrec [_ECD_OFFSET ]) # Central directory is on the same disk
243- if fp .tell () == endrec [_ECD_OFFSET ] and endrec [_ECD_SIZE ] >= sizeCentralDir :
242+ # Central directory is on the same disk
243+ fp .seek (sum (_handle_prepended_data (endrec )))
244+ if endrec [_ECD_SIZE ] >= sizeCentralDir :
244245 data = fp .read (sizeCentralDir ) # CD is where we expect it to be
245246 if len (data ) == sizeCentralDir :
246247 centdir = struct .unpack (structCentralDir , data ) # CD is the right size
@@ -268,6 +269,22 @@ def is_zipfile(filename):
268269 pass
269270 return result
270271
272+ def _handle_prepended_data (endrec , debug = 0 ):
273+ size_cd = endrec [_ECD_SIZE ] # bytes in central directory
274+ offset_cd = endrec [_ECD_OFFSET ] # offset of central directory
275+
276+ # "concat" is zero, unless zip was concatenated to another file
277+ concat = endrec [_ECD_LOCATION ] - size_cd - offset_cd
278+ if endrec [_ECD_SIGNATURE ] == stringEndArchive64 :
279+ # If Zip64 extension structures are present, account for them
280+ concat -= (sizeEndCentDir64 + sizeEndCentDir64Locator )
281+
282+ if debug > 2 :
283+ inferred = concat + offset_cd
284+ print ("given, inferred, offset" , offset_cd , inferred , concat )
285+
286+ return offset_cd , concat
287+
271288def _EndRecData64 (fpin , offset , endrec ):
272289 """
273290 Read the ZIP64 end-of-archive records and use that to update endrec
@@ -1511,28 +1528,21 @@ def _RealGetContents(self):
15111528 raise BadZipFile ("File is not a zip file" )
15121529 if self .debug > 1 :
15131530 print (endrec )
1514- size_cd = endrec [_ECD_SIZE ] # bytes in central directory
1515- offset_cd = endrec [_ECD_OFFSET ] # offset of central directory
15161531 self ._comment = endrec [_ECD_COMMENT ] # archive comment
15171532
1518- # "concat" is zero, unless zip was concatenated to another file
1519- concat = endrec [_ECD_LOCATION ] - size_cd - offset_cd
1520- if endrec [_ECD_SIGNATURE ] == stringEndArchive64 :
1521- # If Zip64 extension structures are present, account for them
1522- concat -= (sizeEndCentDir64 + sizeEndCentDir64Locator )
1533+ offset_cd , concat = _handle_prepended_data (endrec , self .debug )
1534+
1535+ # self.start_dir: Position of start of central directory
1536+ self .start_dir = offset_cd + concat
15231537
15241538 # store the offset to the beginning of data for the
15251539 # .data_offset property
15261540 self ._data_offset = concat
15271541
1528- if self .debug > 2 :
1529- inferred = concat + offset_cd
1530- print ("given, inferred, offset" , offset_cd , inferred , concat )
1531- # self.start_dir: Position of start of central directory
1532- self .start_dir = offset_cd + concat
15331542 if self .start_dir < 0 :
15341543 raise BadZipFile ("Bad offset for central directory" )
15351544 fp .seek (self .start_dir , 0 )
1545+ size_cd = endrec [_ECD_SIZE ]
15361546 data = fp .read (size_cd )
15371547 fp = io .BytesIO (data )
15381548 total = 0
0 commit comments