Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
zipfile: handle extras after a zip64 extra
Previously, any data _after_ the zip64 extra would be removed.

With many new tests.

Fixes #88233
  • Loading branch information
thatch committed Sep 5, 2022
commit a263718a19eb7828b114a2634d2fe8895c42dbf6
52 changes: 52 additions & 0 deletions Lib/test/test_zipfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -3425,6 +3425,58 @@ def test_cli_with_metadata_encoding_extract(self):
for name in self.file_names:
self.assertIn(name, listing)

class StripExtraTests(unittest.TestCase):
# Note: all of the "z" characters are technically invalid, but up to 3 bytes
# at the end of the extra will be passed through as they are too short to
# encode a valid extra.
def test_no_data(self):
s = struct.Struct("<HH")
a = s.pack(1, 0) # 1=zip64 exta signature
b = s.pack(2, 0)
c = s.pack(3, 0)

self.assertEqual(b'', zipfile._strip_extra(a, (1,)))
self.assertEqual(b, zipfile._strip_extra(b, (1,)))
self.assertEqual(b+b"z", zipfile._strip_extra(b+b"z", (1,)))

self.assertEqual(b+c, zipfile._strip_extra(a+b+c, (1,)))
self.assertEqual(b+c, zipfile._strip_extra(b+a+c, (1,)))
self.assertEqual(b+c, zipfile._strip_extra(b+c+a, (1,)))

def test_with_data(self):
s = struct.Struct("<HH")
a = s.pack(1, 1) + b"a" # 1=zip64 exta signature
b = s.pack(2, 2) + b"bb"
c = s.pack(3, 3) + b"ccc"

self.assertEqual(b"", zipfile._strip_extra(a, (1,)))
self.assertEqual(b, zipfile._strip_extra(b, (1,)))
self.assertEqual(b+b"z", zipfile._strip_extra(b+b"z", (1,)))

self.assertEqual(b+c, zipfile._strip_extra(a+b+c, (1,)))
self.assertEqual(b+c, zipfile._strip_extra(b+a+c, (1,)))
self.assertEqual(b+c, zipfile._strip_extra(b+c+a, (1,)))

def test_multiples(self):
s = struct.Struct("<HH")
a = s.pack(1, 1) + b"a" # 1=zip64 exta signature
b = s.pack(2, 2) + b"bb"
c = s.pack(3, 3) + b"ccc"

self.assertEqual(b"", zipfile._strip_extra(a+a, (1,)))
self.assertEqual(b"", zipfile._strip_extra(a+a+a, (1,)))
self.assertEqual(b"z", zipfile._strip_extra(a+a+b"z", (1,)))
self.assertEqual(b+b"z", zipfile._strip_extra(a+a+b+b"z", (1,)))

self.assertEqual(b, zipfile._strip_extra(a+a+b, (1,)))
self.assertEqual(b, zipfile._strip_extra(a+b+a, (1,)))
self.assertEqual(b, zipfile._strip_extra(b+a+a, (1,)))

def test_too_short(self):
self.assertEqual(b"", zipfile._strip_extra(b"", (1,)))
self.assertEqual(b"z", zipfile._strip_extra(b"z", (1,)))
self.assertEqual(b"zz", zipfile._strip_extra(b"zz", (1,)))
self.assertEqual(b"zzz", zipfile._strip_extra(b"zzz", (1,)))

if __name__ == "__main__":
unittest.main()
2 changes: 2 additions & 0 deletions Lib/zipfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,8 @@ def _strip_extra(extra, xids):
i = j
if not modified:
return extra
if start != len(extra):
buffer.append(extra[start:])
return b''.join(buffer)

def _check_zipfile(fp):
Expand Down