@@ -205,19 +205,22 @@ def __init__(self, val, id=None):
205205 self .id = id
206206
207207 @classmethod
208- def read_one (cls , raw ):
208+ def read_one (cls , raw , validate = False ):
209209 try :
210210 xid , xlen = cls .FIELD_STRUCT .unpack_from (raw )
211211 except struct .error :
212212 xid , xlen = None , 0
213+ else :
214+ if validate and xlen + 4 > len (raw ):
215+ raise BadZipFile ("Corrupt extra field %04x (size=%d)" % (xid , xlen ))
213216 return cls (raw [:4 + xlen ], xid ), raw [4 + xlen :]
214217
215218 @classmethod
216- def split (cls , data ):
219+ def split (cls , data , validate = False ):
217220 # use memoryview for zero-copy slices
218221 rest = memoryview (data )
219222 while rest :
220- extra , rest = cls .read_one (rest )
223+ extra , rest = cls .read_one (rest , validate = validate )
221224 yield extra
222225
223226 @classmethod
@@ -584,14 +587,11 @@ def _encodeFilenameFlags(self):
584587
585588 def _decodeExtra (self , filename_crc ):
586589 # Try to decode the extra field.
587- extra = self .extra
588590 unpack = struct .unpack
589- while len (extra ) >= 4 :
590- tp , ln = unpack ('<HH' , extra [:4 ])
591- if ln + 4 > len (extra ):
592- raise BadZipFile ("Corrupt extra field %04x (size=%d)" % (tp , ln ))
591+ for extra in _Extra .split (self .extra , True ):
592+ tp = extra .id
593593 if tp == 0x0001 :
594- data = extra [4 :ln + 4 ]
594+ data = extra [4 :]
595595 # ZIP64 extension (large files and/or large archives)
596596 try :
597597 if self .file_size in (0xFFFF_FFFF_FFFF_FFFF , 0xFFFF_FFFF ):
@@ -609,7 +609,7 @@ def _decodeExtra(self, filename_crc):
609609 raise BadZipFile (f"Corrupt zip64 extra field. "
610610 f"{ field } not found." ) from None
611611 elif tp == 0x7075 :
612- data = extra [4 :ln + 4 ]
612+ data = extra [4 :]
613613 # Unicode Path Extra Field
614614 try :
615615 up_version , up_name_crc = unpack ('<BL' , data [:5 ])
@@ -625,8 +625,6 @@ def _decodeExtra(self, filename_crc):
625625 except UnicodeDecodeError as e :
626626 raise BadZipFile ('Corrupt unicode path extra field (0x7075): invalid utf-8 bytes' ) from e
627627
628- extra = extra [ln + 4 :]
629-
630628 @classmethod
631629 def from_file (cls , filename , arcname = None , * , strict_timestamps = True ):
632630 """Construct an appropriate ZipInfo for a file on the filesystem.
0 commit comments