@@ -36,8 +36,8 @@ class ZIPHandler(StructHandler):
3636 uint16 internal_file_attr;
3737 uint32 external_file_attr;
3838 uint32 relative_offset_local_header;
39- char file_name[file_name_length];
40- char extra_field[extra_field_length];
39+ // char file_name[file_name_length];
40+ // char extra_field[extra_field_length];
4141 } cd_file_header_t;
4242
4343 typedef struct end_of_central_directory
@@ -95,6 +95,9 @@ def has_encrypted_files(
9595 file .seek (start_offset + end_of_central_directory .offset_of_cd , io .SEEK_SET )
9696 for _ in range (end_of_central_directory .total_entries ):
9797 cd_header = self .cparser_le .cd_file_header_t (file )
98+ file .seek (
99+ cd_header .file_name_length + cd_header .extra_field_length , io .SEEK_CUR
100+ )
98101 if cd_header .flags & self .ENCRYPTED_FLAG :
99102 return True
100103 return False
@@ -111,6 +114,14 @@ def is_zip64_eocd(end_of_central_directory: Instance):
111114 or end_of_central_directory .offset_of_cd == 0xFFFFFFFF
112115 )
113116
117+ @staticmethod
118+ def is_zip64_cd (central_directory : Instance ):
119+ # see https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT section 4.3.9.2
120+ return (
121+ central_directory .file_size == 0xFFFFFFFF
122+ or central_directory .compress_size == 0xFFFFFFFF
123+ )
124+
114125 def _parse_zip64 (self , file : File , start_offset : int , offset : int ) -> Instance :
115126 file .seek (start_offset , io .SEEK_SET )
116127 for eocd_locator_offset in iterate_patterns (
@@ -137,6 +148,20 @@ def _parse_zip64(self, file: File, start_offset: int, offset: int) -> Instance:
137148 "Missing ZIP64 EOCD locator record header in ZIP chunk."
138149 )
139150
151+ def is_zip64 (self , file , start_offset , offset , end_of_central_directory ):
152+ absolute_offset_of_cd = start_offset + end_of_central_directory .offset_of_cd
153+
154+ if 0 < absolute_offset_of_cd < offset :
155+ file .seek (absolute_offset_of_cd , io .SEEK_SET )
156+ central_directory = self .cparser_le .cd_file_header_t (file )
157+ if self .is_zip64_cd (central_directory ):
158+ return True
159+
160+ # some values in the CD can be FFFF, indicating its a zip64
161+ # if the offset of the CD is 0xFFFFFFFF, its definitely one
162+ # otherwise we check every other header indicating zip64
163+ return self .is_zip64_eocd (end_of_central_directory )
164+
140165 def calculate_chunk (self , file : File , start_offset : int ) -> Optional [ValidChunk ]:
141166 has_encrypted_files = False
142167 file .seek (start_offset , io .SEEK_SET )
@@ -147,7 +172,8 @@ def calculate_chunk(self, file: File, start_offset: int) -> Optional[ValidChunk]
147172 file .seek (offset , io .SEEK_SET )
148173 end_of_central_directory = self .parse_header (file )
149174
150- if self .is_zip64_eocd (end_of_central_directory ):
175+ if self .is_zip64 (file , start_offset , offset , end_of_central_directory ):
176+ file .seek (offset , io .SEEK_SET )
151177 end_of_central_directory = self ._parse_zip64 (file , start_offset , offset )
152178 break
153179
0 commit comments