Skip to content
Closed
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 authored and jaraco committed Feb 20, 2023
commit dae825bad06f03250dbfe30af689e61675ee9a23
52 changes: 52 additions & 0 deletions Lib/test/test_zipfile/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -3009,6 +3009,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/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,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