Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Fix Zip64 extensions not being properly applied in some cases
This commit fixes an issue where adding a small file to a `ZipFile`
object while forcing zip64 extensions causes an extra Zip64 record to be
added to the zip, but doesn't update the `min_version` or file sizes.

Fixes #103861
  • Loading branch information
pR0Ps committed Apr 27, 2023
commit c42700d10362ea6299ee40b3463dcb8a1043734e
35 changes: 35 additions & 0 deletions Lib/test/test_zipfile/test_core.py
Comment thread
pR0Ps marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -1080,6 +1080,41 @@ def test_generated_valid_zip64_extra(self):
self.assertEqual(zinfo.header_offset, expected_header_offset)
self.assertEqual(zf.read(zinfo), expected_content)

def test_force_zip64(self):
"""Test that forcing zip64 extensions correctly notes this in the zip file"""
data = io.BytesIO()
with zipfile.ZipFile(data, mode="w", allowZip64=True) as zf:
with zf.open("text.txt", mode="w", force_zip64=True) as zi:
zi.write(b"_")

zipdata = data.getvalue()

# pull out and check zip information
(
header, vers, os, flags, comp, csize, usize, fn_len,
ex_total_len, filename, ex_id, ex_len, ex_usize, ex_csize, cd_sig
) = struct.unpack("<4sBBHH8xIIHH8shhQQx4s", zipdata[:63])

self.assertEqual(header, b"PK\x03\x04") # local file header
self.assertGreaterEqual(vers, zipfile.ZIP64_VERSION) # requires zip64 to extract
Comment thread
gpshead marked this conversation as resolved.
self.assertEqual(os, 0) # compatible with MS-DOS
self.assertEqual(flags, 0) # no flags
self.assertEqual(comp, 0) # compression method = stored
self.assertEqual(csize, 0xFFFFFFFF) # sizes are in zip64 extra
self.assertEqual(usize, 0xFFFFFFFF)
self.assertEqual(fn_len, 8) # filename len
self.assertEqual(ex_total_len, 20) # size of extra records
self.assertEqual(ex_id, 1) # Zip64 extra record
self.assertEqual(ex_len, 16) # 16 bytes of data
self.assertEqual(ex_usize, 1) # uncompressed size
self.assertEqual(ex_csize, 1) # compressed size
self.assertEqual(cd_sig, b"PK\x01\x02") # ensure the central directory header is next

z = zipfile.ZipFile(io.BytesIO(zipdata))
zinfos = z.infolist()
self.assertEqual(len(zinfos), 1)
self.assertGreaterEqual(zinfos[0].extract_version, zipfile.ZIP64_VERSION) # requires zip64 to extract


@requires_zlib()
class DeflateTestZip64InSmallFiles(AbstractTestZip64InSmallFiles,
Expand Down
12 changes: 5 additions & 7 deletions Lib/zipfile/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -455,17 +455,15 @@ def FileHeader(self, zip64=None):
extra = self.extra

min_version = 0
if zip64 is None:
zip64 = file_size > ZIP64_LIMIT or compress_size > ZIP64_LIMIT
if (file_size > ZIP64_LIMIT or compress_size > ZIP64_LIMIT):
if zip64 is None:
zip64 = True
elif not zip64:
raise LargeZipFile("Filesize would require ZIP64 extensions")
if zip64:
fmt = '<HHQQ'
extra = extra + struct.pack(fmt,
1, struct.calcsize(fmt)-4, file_size, compress_size)
if file_size > ZIP64_LIMIT or compress_size > ZIP64_LIMIT:
if not zip64:
raise LargeZipFile("Filesize would require ZIP64 extensions")
# File is larger than what fits into a 4 byte integer,
# fall back to the ZIP64 extension
file_size = 0xffffffff
compress_size = 0xffffffff
min_version = ZIP64_VERSION
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix ``zipfile.Zipfile`` creating invalid zip files when ``force_zip64`` was
used to add files to them. Patch by Carey Metcalfe.