From 0551a0ec8671fc58bd3c23811f903f1f805efe7f Mon Sep 17 00:00:00 2001 From: Carey Metcalfe Date: Tue, 25 Apr 2023 20:01:04 -0400 Subject: [PATCH] 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 --- Lib/test/test_zipfile/test_core.py | 37 +++++++++++++++++++ Lib/zipfile/__init__.py | 12 +++--- ...-04-25-19-58-13.gh-issue-103861.JeozgD.rst | 2 + 3 files changed, 44 insertions(+), 7 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2023-04-25-19-58-13.gh-issue-103861.JeozgD.rst diff --git a/Lib/test/test_zipfile/test_core.py b/Lib/test/test_zipfile/test_core.py index 73c6b0185a1a0e4..bb78b29a6e4319c 100644 --- a/Lib/test/test_zipfile/test_core.py +++ b/Lib/test/test_zipfile/test_core.py @@ -1080,6 +1080,43 @@ 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() + + # check for file header + self.assertEqual(zipdata[:4], b"PK\x03\x04") + + # pull out and check file information + ( + vers, os, flags, comp, _, _, crc, csize, usize, fn_len, + ex_total_len, filename, ex_id, ex_len, ex_usize, ex_csize + ) = struct.unpack(" 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 = ' 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 diff --git a/Misc/NEWS.d/next/Library/2023-04-25-19-58-13.gh-issue-103861.JeozgD.rst b/Misc/NEWS.d/next/Library/2023-04-25-19-58-13.gh-issue-103861.JeozgD.rst new file mode 100644 index 000000000000000..cc1c444449fe936 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2023-04-25-19-58-13.gh-issue-103861.JeozgD.rst @@ -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.