Skip to content

Commit ac27728

Browse files
committed
gh-152486: Fix duplicated zip64 extra in local file entry
1 parent 65585ca commit ac27728

3 files changed

Lines changed: 36 additions & 2 deletions

File tree

Lib/test/test_zipfile/test_core.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1189,6 +1189,34 @@ def test_generated_valid_zip64_extra(self):
11891189
self.assertEqual(zinfo.header_offset, expected_header_offset)
11901190
self.assertEqual(zf.read(zinfo), expected_content)
11911191

1192+
def test_generated_valid_zip64_extra_in_local_entry(self):
1193+
"""Should not write duplicated zip64 fields to the local file entry."""
1194+
fh = io.BytesIO()
1195+
with zipfile.ZipFile(fh, 'w') as zh:
1196+
zinfo = zipfile.ZipInfo('strfile')
1197+
zinfo.extra = (
1198+
# zip64 (should be stripped)
1199+
b'\x01\x00\x10\x00'
1200+
b'\x00\x00\x00\x00\x00\x00\x00\x00'
1201+
b'\x00\x00\x00\x00\x00\x00\x00\x00'
1202+
1203+
# invalid tail
1204+
b'zzz'
1205+
)
1206+
zh.writestr(zinfo, self.data)
1207+
1208+
fh.seek(0)
1209+
fh.seek(zinfo.header_offset)
1210+
entry = fh.read(zh.start_dir - zinfo.header_offset - zinfo.compress_size)
1211+
header = struct.unpack_from(zipfile.structFileHeader, entry)
1212+
extra_bytes = entry[-header[zipfile._FH_EXTRA_FIELD_LENGTH]:]
1213+
self.assertEqual(extra_bytes, (
1214+
b'\x01\x00\x10\x00'
1215+
b'!e\x00\x00\x00\x00\x00\x00'
1216+
b'!e\x00\x00\x00\x00\x00\x00'
1217+
b'zzz'
1218+
))
1219+
11921220
def test_force_zip64(self):
11931221
"""Test that forcing zip64 extensions correctly notes this in the zip file"""
11941222

Lib/zipfile/__init__.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -550,8 +550,13 @@ def FileHeader(self, zip64=None):
550550
zip64 = file_size > ZIP64_LIMIT or compress_size > ZIP64_LIMIT
551551
if zip64:
552552
fmt = '<HHQQ'
553-
extra = extra + struct.pack(fmt,
554-
1, struct.calcsize(fmt)-4, file_size, compress_size)
553+
554+
# Prepend a ZIP64 field to extra data
555+
extra = struct.pack(
556+
fmt, 1, struct.calcsize(fmt)-4,
557+
file_size, compress_size
558+
) + _Extra.strip(extra, (1,))
559+
555560
file_size = 0xffffffff
556561
compress_size = 0xffffffff
557562
min_version = ZIP64_VERSION
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix an issue where duplicated Zip64 extra fields were written if :attr:`ZipInfo.extra <zipfile.ZipInfo.extra>` already contained a Zip64 field.

0 commit comments

Comments
 (0)