Skip to content

Commit a263718

Browse files
committed
zipfile: handle extras after a zip64 extra
Previously, any data _after_ the zip64 extra would be removed. With many new tests. Fixes #88233
1 parent 80a9bd2 commit a263718

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

Lib/test/test_zipfile.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3425,6 +3425,58 @@ def test_cli_with_metadata_encoding_extract(self):
34253425
for name in self.file_names:
34263426
self.assertIn(name, listing)
34273427

3428+
class StripExtraTests(unittest.TestCase):
3429+
# Note: all of the "z" characters are technically invalid, but up to 3 bytes
3430+
# at the end of the extra will be passed through as they are too short to
3431+
# encode a valid extra.
3432+
def test_no_data(self):
3433+
s = struct.Struct("<HH")
3434+
a = s.pack(1, 0) # 1=zip64 exta signature
3435+
b = s.pack(2, 0)
3436+
c = s.pack(3, 0)
3437+
3438+
self.assertEqual(b'', zipfile._strip_extra(a, (1,)))
3439+
self.assertEqual(b, zipfile._strip_extra(b, (1,)))
3440+
self.assertEqual(b+b"z", zipfile._strip_extra(b+b"z", (1,)))
3441+
3442+
self.assertEqual(b+c, zipfile._strip_extra(a+b+c, (1,)))
3443+
self.assertEqual(b+c, zipfile._strip_extra(b+a+c, (1,)))
3444+
self.assertEqual(b+c, zipfile._strip_extra(b+c+a, (1,)))
3445+
3446+
def test_with_data(self):
3447+
s = struct.Struct("<HH")
3448+
a = s.pack(1, 1) + b"a" # 1=zip64 exta signature
3449+
b = s.pack(2, 2) + b"bb"
3450+
c = s.pack(3, 3) + b"ccc"
3451+
3452+
self.assertEqual(b"", zipfile._strip_extra(a, (1,)))
3453+
self.assertEqual(b, zipfile._strip_extra(b, (1,)))
3454+
self.assertEqual(b+b"z", zipfile._strip_extra(b+b"z", (1,)))
3455+
3456+
self.assertEqual(b+c, zipfile._strip_extra(a+b+c, (1,)))
3457+
self.assertEqual(b+c, zipfile._strip_extra(b+a+c, (1,)))
3458+
self.assertEqual(b+c, zipfile._strip_extra(b+c+a, (1,)))
3459+
3460+
def test_multiples(self):
3461+
s = struct.Struct("<HH")
3462+
a = s.pack(1, 1) + b"a" # 1=zip64 exta signature
3463+
b = s.pack(2, 2) + b"bb"
3464+
c = s.pack(3, 3) + b"ccc"
3465+
3466+
self.assertEqual(b"", zipfile._strip_extra(a+a, (1,)))
3467+
self.assertEqual(b"", zipfile._strip_extra(a+a+a, (1,)))
3468+
self.assertEqual(b"z", zipfile._strip_extra(a+a+b"z", (1,)))
3469+
self.assertEqual(b+b"z", zipfile._strip_extra(a+a+b+b"z", (1,)))
3470+
3471+
self.assertEqual(b, zipfile._strip_extra(a+a+b, (1,)))
3472+
self.assertEqual(b, zipfile._strip_extra(a+b+a, (1,)))
3473+
self.assertEqual(b, zipfile._strip_extra(b+a+a, (1,)))
3474+
3475+
def test_too_short(self):
3476+
self.assertEqual(b"", zipfile._strip_extra(b"", (1,)))
3477+
self.assertEqual(b"z", zipfile._strip_extra(b"z", (1,)))
3478+
self.assertEqual(b"zz", zipfile._strip_extra(b"zz", (1,)))
3479+
self.assertEqual(b"zzz", zipfile._strip_extra(b"zzz", (1,)))
34283480

34293481
if __name__ == "__main__":
34303482
unittest.main()

Lib/zipfile.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,8 @@ def _strip_extra(extra, xids):
211211
i = j
212212
if not modified:
213213
return extra
214+
if start != len(extra):
215+
buffer.append(extra[start:])
214216
return b''.join(buffer)
215217

216218
def _check_zipfile(fp):

0 commit comments

Comments
 (0)