Skip to content

Commit d1afcb3

Browse files
committed
fix(handler): add support for zip64 values in Central Directory Headers
1 parent fb8c965 commit d1afcb3

File tree

6 files changed

+34
-1
lines changed

6 files changed

+34
-1
lines changed

blue.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
blue

red.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
red
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
version https://git-lfs.github.com/spec/v1
2+
oid sha256:a59995571929d2047445ef9ead25ebe1560a6b52a8204ed342c72f8eb624bec9
3+
size 457
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
version https://git-lfs.github.com/spec/v1
2+
oid sha256:a0bee6616b5e5eae6799cb4525a884a82e7161614f11122bbdf4383b2ac05998
3+
size 5
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
version https://git-lfs.github.com/spec/v1
2+
oid sha256:6ace33171ce0acb6891e3cc311d75a97aa429d77c05cba600d49ed9652ed49de
3+
size 4

unblob/handlers/archive/zip.py

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,14 @@ def is_zip64_eocd(end_of_central_directory: Instance):
111111
or end_of_central_directory.offset_of_cd == 0xFFFFFFFF
112112
)
113113

114+
@staticmethod
115+
def is_zip64_cd(central_directory: Instance):
116+
# see https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT section 4.3.9.2
117+
return (
118+
central_directory.file_size == 0xFFFFFFFF
119+
or central_directory.compress_size == 0xFFFFFFFF
120+
)
121+
114122
def _parse_zip64(self, file: File, start_offset: int, offset: int) -> Instance:
115123
file.seek(start_offset, io.SEEK_SET)
116124
for eocd_locator_offset in iterate_patterns(
@@ -147,7 +155,21 @@ def calculate_chunk(self, file: File, start_offset: int) -> Optional[ValidChunk]
147155
file.seek(offset, io.SEEK_SET)
148156
end_of_central_directory = self.parse_header(file)
149157

150-
if self.is_zip64_eocd(end_of_central_directory):
158+
# some values in the CD can be FFFF, indicating its a zip64
159+
# if the offset of the CD is 0xFFFFFFFF, its definitely one
160+
# otherwise we check every other header indicating zip64
161+
if end_of_central_directory.offset_of_cd == 0xFFFFFFFF:
162+
file.seek(offset, io.SEEK_SET)
163+
end_of_central_directory = self._parse_zip64(file, start_offset, offset)
164+
break
165+
166+
file.seek(end_of_central_directory.offset_of_cd, io.SEEK_SET)
167+
central_directory = self.cparser_le.cd_file_header_t(file)
168+
169+
if self.is_zip64_eocd(end_of_central_directory) or self.is_zip64_cd(
170+
central_directory
171+
):
172+
file.seek(offset, io.SEEK_SET)
151173
end_of_central_directory = self._parse_zip64(file, start_offset, offset)
152174
break
153175

0 commit comments

Comments
 (0)