diff options
author | Tim Hatch <tim@timhatch.com> | 2023-02-20 17:07:03 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-02-20 17:07:03 (GMT) |
commit | 59e86caca812fc993c5eb7dc8ccd1508ffccba86 (patch) | |
tree | f667e940591ba09c44ff51635453c71e0ded890b | |
parent | ed01addb59a554804995303ad3e7bf0c6067737b (diff) | |
download | cpython-59e86caca812fc993c5eb7dc8ccd1508ffccba86.zip cpython-59e86caca812fc993c5eb7dc8ccd1508ffccba86.tar.gz cpython-59e86caca812fc993c5eb7dc8ccd1508ffccba86.tar.bz2 |
gh-88233: zipfile: handle extras after a zip64 extra (GH-96161)
Previously, any data _after_ the zip64 extra would be removed.
With many new tests.
Fixes #88233
Automerge-Triggered-By: GH:jaraco
-rw-r--r-- | Lib/test/test_zipfile/test_core.py | 62 | ||||
-rw-r--r-- | Lib/zipfile/__init__.py | 2 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2022-09-05-12-17-34.gh-issue-88233.gff9qJ.rst | 2 |
3 files changed, 66 insertions, 0 deletions
diff --git a/Lib/test/test_zipfile/test_core.py b/Lib/test/test_zipfile/test_core.py index cf41d0e8..e23f5c2 100644 --- a/Lib/test/test_zipfile/test_core.py +++ b/Lib/test/test_zipfile/test_core.py @@ -3010,5 +3010,67 @@ class EncodedMetadataTests(unittest.TestCase): 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. + + ZIP64_EXTRA = 1 + + def test_no_data(self): + s = struct.Struct("<HH") + a = s.pack(self.ZIP64_EXTRA, 0) + b = s.pack(2, 0) + c = s.pack(3, 0) + + self.assertEqual(b'', zipfile._strip_extra(a, (self.ZIP64_EXTRA,))) + self.assertEqual(b, zipfile._strip_extra(b, (self.ZIP64_EXTRA,))) + self.assertEqual( + b+b"z", zipfile._strip_extra(b+b"z", (self.ZIP64_EXTRA,))) + + self.assertEqual(b+c, zipfile._strip_extra(a+b+c, (self.ZIP64_EXTRA,))) + self.assertEqual(b+c, zipfile._strip_extra(b+a+c, (self.ZIP64_EXTRA,))) + self.assertEqual(b+c, zipfile._strip_extra(b+c+a, (self.ZIP64_EXTRA,))) + + def test_with_data(self): + s = struct.Struct("<HH") + a = s.pack(self.ZIP64_EXTRA, 1) + b"a" + b = s.pack(2, 2) + b"bb" + c = s.pack(3, 3) + b"ccc" + + self.assertEqual(b"", zipfile._strip_extra(a, (self.ZIP64_EXTRA,))) + self.assertEqual(b, zipfile._strip_extra(b, (self.ZIP64_EXTRA,))) + self.assertEqual( + b+b"z", zipfile._strip_extra(b+b"z", (self.ZIP64_EXTRA,))) + + self.assertEqual(b+c, zipfile._strip_extra(a+b+c, (self.ZIP64_EXTRA,))) + self.assertEqual(b+c, zipfile._strip_extra(b+a+c, (self.ZIP64_EXTRA,))) + self.assertEqual(b+c, zipfile._strip_extra(b+c+a, (self.ZIP64_EXTRA,))) + + def test_multiples(self): + s = struct.Struct("<HH") + a = s.pack(self.ZIP64_EXTRA, 1) + b"a" + b = s.pack(2, 2) + b"bb" + + self.assertEqual(b"", zipfile._strip_extra(a+a, (self.ZIP64_EXTRA,))) + self.assertEqual(b"", zipfile._strip_extra(a+a+a, (self.ZIP64_EXTRA,))) + self.assertEqual( + b"z", zipfile._strip_extra(a+a+b"z", (self.ZIP64_EXTRA,))) + self.assertEqual( + b+b"z", zipfile._strip_extra(a+a+b+b"z", (self.ZIP64_EXTRA,))) + + self.assertEqual(b, zipfile._strip_extra(a+a+b, (self.ZIP64_EXTRA,))) + self.assertEqual(b, zipfile._strip_extra(a+b+a, (self.ZIP64_EXTRA,))) + self.assertEqual(b, zipfile._strip_extra(b+a+a, (self.ZIP64_EXTRA,))) + + def test_too_short(self): + self.assertEqual(b"", zipfile._strip_extra(b"", (self.ZIP64_EXTRA,))) + self.assertEqual(b"z", zipfile._strip_extra(b"z", (self.ZIP64_EXTRA,))) + self.assertEqual( + b"zz", zipfile._strip_extra(b"zz", (self.ZIP64_EXTRA,))) + self.assertEqual( + b"zzz", zipfile._strip_extra(b"zzz", (self.ZIP64_EXTRA,))) + + if __name__ == "__main__": unittest.main() diff --git a/Lib/zipfile/__init__.py b/Lib/zipfile/__init__.py index e1833dd..6e6211d 100644 --- a/Lib/zipfile/__init__.py +++ b/Lib/zipfile/__init__.py @@ -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): diff --git a/Misc/NEWS.d/next/Library/2022-09-05-12-17-34.gh-issue-88233.gff9qJ.rst b/Misc/NEWS.d/next/Library/2022-09-05-12-17-34.gh-issue-88233.gff9qJ.rst new file mode 100644 index 0000000..806f701 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-09-05-12-17-34.gh-issue-88233.gff9qJ.rst @@ -0,0 +1,2 @@ +Correctly preserve "extra" fields in ``zipfile`` regardless of their +ordering relative to a zip64 "extra." |