bpo-34341: Fix appending to ZIP archives with the ZIP64 extension. (GH-8683)
This commit is contained in:
parent
da8d72c953
commit
9bdb7be482
|
@ -770,6 +770,20 @@ class StoredTestZip64InSmallFiles(AbstractTestZip64InSmallFiles,
|
|||
with zipfile.ZipFile(TESTFN2, "r", zipfile.ZIP_STORED) as zipfp:
|
||||
self.assertEqual(zipfp.namelist(), ["absolute"])
|
||||
|
||||
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)
|
||||
|
||||
@requires_zlib
|
||||
class DeflateTestZip64InSmallFiles(AbstractTestZip64InSmallFiles,
|
||||
unittest.TestCase):
|
||||
|
|
|
@ -159,6 +159,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):
|
||||
|
@ -1819,6 +1840,7 @@ class ZipFile:
|
|||
min_version = 0
|
||||
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
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
Appending to the ZIP archive with the ZIP64 extension no longer grows the
|
||||
size of extra fields of existing entries.
|
Loading…
Reference in New Issue