8000 [2.7] bpo-34341: Fix appending to ZIP archives with the ZIP64 extensi… · python/cpython@29034ba · GitHub
[go: up one dir, main page]

Skip to content

Commit 29034ba

Browse files
[2.7] bpo-34341: Fix appending to ZIP archives with the ZIP64 extension. (GH-8683). (GH-9400)
(cherry picked from commit 9bdb7be)
1 parent 18b20ba commit 29034ba

File tree

3 files changed

+38
-0
lines changed

3 files changed

+38
-0
lines changed

Lib/test/test_zipfile.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -812,6 +812,20 @@ def test_too_many_files_append(self):
812812
self.assertEqual(content, "%d" % (i**3 % 57))
813813
zipf2.close()
814814

815+
def test_append(self):
816+
# Test that appending to the Zip64 archive doesn't change
817+
# extra fields of existing entries.
818+
with zipfile.ZipFile(TESTFN2, "w", allowZip64=True) as zipfp:
819+
zipfp.writestr("strfile", self.data)
820+
with zipfile.ZipFile(TESTFN2, "r", allowZip64=True) as zipfp:
821+
zinfo = zipfp.getinfo("strfile")
822+
extra = zinfo.extra
823+
with zipfile.ZipFile(TESTFN2, "a", allowZip64=True) as zipfp:
824+
zipfp.writestr("strfile2", self.data)
825+
with zipfile.ZipFile(TESTFN2, "r", allowZip64=True) as zipfp:
826+
zinfo = zipfp.getinfo("strfile")
827+
self.assertEqual(zinfo.extra, extra)
828+
815829
def tearDown(self):
816830
zipfile.ZIP64_LIMIT = self._limit
817831
zipfile.ZIP_FILECOUNT_LIMIT = self._filecount_limit

Lib/zipfile.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,27 @@ class LargeZipFile(Exception):
131131
_CD64_DIRECTORY_SIZE = 8
132132
_CD64_OFFSET_START_CENTDIR = 9
133133

134+
_EXTRA_FIELD_STRUCT = struct.Struct('<HH')
135+
136+
def _strip_extra(extra, xids):
137+
# Remove Extra Fields with specified IDs.
138+
unpack = _EXTRA_FIELD_STRUCT.unpack
139+
modified = False
140+
buffer = []
141+
start = i = 0
142+
while i + 4 <= len(extra):
143+
xid, xlen = unpack(extra[i : i + 4])
144+
j = i + 4 + xlen
145+
if xid in xids:
146+
if i != start:
147+
buffer.append(extra[start : i])
148+
start = j
149+
modified = True
150+
i = j
151+
if not modified:
152+
return extra
153+
return b''.join(buffer)
154+
134155
def _check_zipfile(fp):
135156
try:
136157
if _EndRecData(fp):
@@ -1293,6 +1314,7 @@ def close(self):
12931314
extra_data = zinfo.extra
12941315
if extra:
12951316
# Append a ZIP64 field to the extra's
1317+
extra_data = _strip_extra(extra_data, (1,))
12961318
extra_data = struct.pack(
12971319
'<HH' + 'Q'*len(extra),
12981320
1, 8*len(extra), *extra) + extra_data
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Appending to the ZIP archive with the ZIP64 extension no longer grows the
2+
size of extra fields of existing entries.

0 commit comments

Comments
 (0)
0