Commit 29034baf authored by Serhiy Storchaka's avatar Serhiy Storchaka Committed by GitHub

[2.7] bpo-34341: Fix appending to ZIP archives with the ZIP64 extension. (GH-8683). (GH-9400)

(cherry picked from commit 9bdb7be4)
parent 18b20bad
......@@ -812,6 +812,20 @@ class TestZip64InSmallFiles(unittest.TestCase):
self.assertEqual(content, "%d" % (i**3 % 57))
zipf2.close()
def test_append(self):
# Test that appending to the Zip64 archive doesn't change
# extra fields of existing entries.
with zipfile.ZipFile(TESTFN2, "w", allowZip64=True) as zipfp:
zipfp.writestr("strfile", self.data)
with zipfile.ZipFile(TESTFN2, "r", allowZip64=True) as zipfp:
zinfo = zipfp.getinfo("strfile")
extra = zinfo.extra
with zipfile.ZipFile(TESTFN2, "a", allowZip64=True) as zipfp:
zipfp.writestr("strfile2", self.data)
with zipfile.ZipFile(TESTFN2, "r", allowZip64=True) as zipfp:
zinfo = zipfp.getinfo("strfile")
self.assertEqual(zinfo.extra, extra)
def tearDown(self):
zipfile.ZIP64_LIMIT = self._limit
zipfile.ZIP_FILECOUNT_LIMIT = self._filecount_limit
......
......@@ -131,6 +131,27 @@ _CD64_NUMBER_ENTRIES_TOTAL = 7
_CD64_DIRECTORY_SIZE = 8
_CD64_OFFSET_START_CENTDIR = 9
_EXTRA_FIELD_STRUCT = struct.Struct('<HH')
def _strip_extra(extra, xids):
# Remove Extra Fields with specified IDs.
unpack = _EXTRA_FIELD_STRUCT.unpack
modified = False
buffer = []
start = i = 0
while i + 4 <= len(extra):
xid, xlen = unpack(extra[i : i + 4])
j = i + 4 + xlen
if xid in xids:
if i != start:
buffer.append(extra[start : i])
start = j
modified = True
i = j
if not modified:
return extra
return b''.join(buffer)
def _check_zipfile(fp):
try:
if _EndRecData(fp):
......@@ -1293,6 +1314,7 @@ class ZipFile(object):
extra_data = zinfo.extra
if extra:
# Append a ZIP64 field to the extra's
extra_data = _strip_extra(extra_data, (1,))
extra_data = struct.pack(
'<HH' + 'Q'*len(extra),
1, 8*len(extra), *extra) + extra_data
......
Appending to the ZIP archive with the ZIP64 extension no longer grows the
size of extra fields of existing entries.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment