@@ -218,8 +218,9 @@ def _check_zipfile(fp):
218218 if endrec [_ECD_ENTRIES_TOTAL ] == 0 and endrec [_ECD_SIZE ] == 0 and endrec [_ECD_OFFSET ] == 0 :
219219 return True # Empty zipfiles are still zipfiles
220220 elif endrec [_ECD_DISK_NUMBER ] == endrec [_ECD_DISK_START ]:
221- fp .seek (endrec [_ECD_OFFSET ]) # Central directory is on the same disk
222- if fp .tell () == endrec [_ECD_OFFSET ] and endrec [_ECD_SIZE ] >= sizeCentralDir :
221+ # Central directory is on the same disk
222+ fp .seek (sum (_handle_prepended_data (endrec )))
223+ if endrec [_ECD_SIZE ] >= sizeCentralDir :
223224 data = fp .read (sizeCentralDir ) # CD is where we expect it to be
224225 if len (data ) == sizeCentralDir :
225226 centdir = struct .unpack (structCentralDir , data ) # CD is the right size
@@ -245,6 +246,21 @@ def is_zipfile(filename):
245246 pass
246247 return result
247248
249+ def _handle_prepended_data (endrec , debug = 0 ):
250+ size_cd = endrec [_ECD_SIZE ] # bytes in central directory
251+ offset_cd = endrec [_ECD_OFFSET ] # offset of central directory
252+
253+ # "concat" is zero, unless zip was concatenated to another file
254+ concat = endrec [_ECD_LOCATION ] - size_cd - offset_cd
255+ if endrec [_ECD_SIGNATURE ] == stringEndArchive64 :
256+ # If Zip64 extension structures are present, account for them
257+ concat -= (sizeEndCentDir64 + sizeEndCentDir64Locator )
258+
259+ if debug > 2 :
260+ inferred = concat + offset_cd
261+ print ("given, inferred, offset" , offset_cd , inferred , concat )
262+ return offset_cd , concat
263+
248264def _EndRecData64 (fpin , offset , endrec ):
249265 """
250266 Read the ZIP64 end-of-archive records and use that to update endrec
@@ -1388,24 +1404,15 @@ def _RealGetContents(self):
13881404 raise BadZipFile ("File is not a zip file" )
13891405 if self .debug > 1 :
13901406 print (endrec )
1391- size_cd = endrec [_ECD_SIZE ] # bytes in central directory
1392- offset_cd = endrec [_ECD_OFFSET ] # offset of central directory
13931407 self ._comment = endrec [_ECD_COMMENT ] # archive comment
13941408
1395- # "concat" is zero, unless zip was concatenated to another file
1396- concat = endrec [_ECD_LOCATION ] - size_cd - offset_cd
1397- if endrec [_ECD_SIGNATURE ] == stringEndArchive64 :
1398- # If Zip64 extension structures are present, account for them
1399- concat -= (sizeEndCentDir64 + sizeEndCentDir64Locator )
1400-
1401- if self .debug > 2 :
1402- inferred = concat + offset_cd
1403- print ("given, inferred, offset" , offset_cd , inferred , concat )
14041409 # self.start_dir: Position of start of central directory
1410+ offset_cd , concat = _handle_prepended_data (endrec , self .debug )
14051411 self .start_dir = offset_cd + concat
14061412 if self .start_dir < 0 :
14071413 raise BadZipFile ("Bad offset for central directory" )
14081414 fp .seek (self .start_dir , 0 )
1415+ size_cd = endrec [_ECD_SIZE ]
14091416 data = fp .read (size_cd )
14101417 fp = io .BytesIO (data )
14111418 total = 0
0 commit comments