@@ -38,6 +38,9 @@ class ZipImportError(ImportError):
3838
3939_module_type = type (sys )
4040
41+ END_CENTRAL_DIR_SIZE = 22
42+ STRING_END_ARCHIVE = b'PK\x05 \x06 '
43+ MAX_COMMENT_LEN = (1 << 16 ) - 1
4144
4245class zipimporter :
4346 """zipimporter(archivepath) -> zipimporter object
@@ -354,16 +357,39 @@ def _read_directory(archive):
354357
355358 with fp :
356359 try :
357- fp .seek (- 22 , 2 )
360+ fp .seek (- END_CENTRAL_DIR_SIZE , 2 )
358361 header_position = fp .tell ()
359- buffer = fp .read (22 )
362+ buffer = fp .read (END_CENTRAL_DIR_SIZE )
360363 except OSError :
361364 raise ZipImportError (f"can't read Zip file: { archive !r} " , path = archive )
362- if len (buffer ) != 22 :
365+ if len (buffer ) != END_CENTRAL_DIR_SIZE :
363366 raise ZipImportError (f"can't read Zip file: { archive !r} " , path = archive )
364- if buffer [:4 ] != b'PK \x05 \x06 ' :
367+ if buffer [:4 ] != STRING_END_ARCHIVE :
365368 # Bad: End of Central Dir signature
366- raise ZipImportError (f'not a Zip file: { archive !r} ' , path = archive )
369+ # Check if there's a comment.
370+ try :
371+ fp .seek (0 , 2 )
372+ file_size = fp .tell ()
373+ except OSError :
374+ raise ZipImportError (f"can't read Zip file: { archive !r} " ,
375+ path = archive )
376+ max_comment_start = max (file_size - MAX_COMMENT_LEN -
377+ END_CENTRAL_DIR_SIZE , 0 )
378+ try :
379+ fp .seek (max_comment_start )
380+ data = fp .read ()
381+ except OSError :
382+ raise ZipImportError (f"can't read Zip file: { archive !r} " ,
383+ path = archive )
384+ pos = data .rfind (STRING_END_ARCHIVE )
385+ if pos < 0 :
386+ raise ZipImportError (f'not a Zip file: { archive !r} ' ,
387+ path = archive )
388+ buffer = data [pos :pos + END_CENTRAL_DIR_SIZE ]
389+ if len (buffer ) != END_CENTRAL_DIR_SIZE :
390+ raise ZipImportError (f"corrupt Zip file: { archive !r} " ,
391+ path = archive )
392+ header_position = file_size - len (data ) + pos
367393
368394 header_size = _unpack_uint32 (buffer [12 :16 ])
369395 header_offset = _unpack_uint32 (buffer [16 :20 ])
0 commit comments