8000 gh-88233: zipfile: handle extras after a zip64 extra (GH-96161) · miss-islington/cpython@0959162 · GitHub
[go: up one dir, main page]

Skip to content

Commit 0959162

Browse files
thatchmiss-islington
authored andcommitted
pythongh-88233: zipfile: handle extras after a zip64 extra (pythonGH-96161)
Previously, any data _after_ the zip64 extra would be removed. With many new tests. Fixes pythonGH-88233 (cherry picked from commit 59e86ca) Co-authored-by: Tim Hatch <tim@timhatch.com> Automerge-Triggered-By: GH:jaraco
1 parent 95f4e2c commit 0959162

File tree

3 files changed

+66
-0
lines changed

3 files changed

+66
-0
lines changed

Lib/test/test_zipfile.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3210,5 +3210,67 @@ def test_inheritance(self, alpharep):
32103210
assert isinstance(file, cls)
32113211

32123212

3213+
class StripExtraTests(unittest.TestCase):
3214+
# Note: all of the "z" characters are technically invalid, but up
3215+
# to 3 bytes at the end of the extra will be passed through as they
3216+
# are too short to encode a valid extra.
3217+
3218+
ZIP64_EXTRA = 1
3219+
3220+
def test_no_data(self):
3221+
s = struct.Struct("<HH")
3222+
a = s.pack(self.ZIP64_EXTRA, 0)
3223+
b = s.pack(2, 0)
3224+
c = s.pack(3, 0)
3225+
3226+
self.assertEqual(b'', zipfile._strip_extra(a, (self.ZIP64_EXTRA,)))
3227+
self.assertEqual(b, zipfile._strip_extra(b, (self.ZIP64_EXTRA,)))
3228+
self.assertEqual(
3229+
b+b"z", zipfile._strip_extra(b+b"z", (self.ZIP64_EXTRA,)))
3230+
3231+
self.assertEqual(b+c, zipfile._strip_extra(a+b+c, (self.ZIP64_EXTRA,)))
3232+
self.assertEqual(b+c, zipfile._strip_extra(b+a+c, (self.ZIP64_EXTRA,)))
3233+
self.assertEqual(b+c, zipfile._strip_extra(b+c+a, (self.ZIP64_EXTRA,)))
3234+
3235+
def test_with_data(self):
3236+
s = struct.Struct("<HH")
3237+
a = s.pack(self.ZIP64_EXTRA, 1) + b"a"
3238+
b = s.pack(2, 2) + b"bb"
3239+
c = s.pack(3, 3) + b"ccc"
3240+
3241+
self.assertEqual(b"", zipfile._strip_extra(a, (self.ZIP64_EXTRA,)))
3242+
self.assertEqual(b, zipfile._strip_extra(b, (self.ZIP64_EXTRA,)))
3243+
self.assertEqual(
3244+
b+b"z", zipfile._strip_extra(b+b"z", (self.ZIP64_EXTRA,)))
3245+
3246+
self.assertEqual(b+c, zipfile._strip_extra(a+b+c, (self.ZIP64_EXTRA,)))
3247+
self.assertEqual(b+c, zipfile._strip_extra(b+a+c, (self.ZIP64_EXTRA,)))
3248+
self.assertEqual(b+c, zipfile._strip_extra(b+c+a, (self.ZIP64_EXTRA,)))
3249+
3250+
def test_multiples(self):
3251+
s = struct.Struct("<HH")
3252+
a = s.pack(self.ZIP64_EXTRA, 1) + b"a"
3253+
b = s.pack(2, 2) + b"bb"
3254+
3255+
self.assertEqual(b"", zipfile._strip_extra(a+a, (self.ZIP64_EXTRA,)))
3256+
self.assertEqual(b"", zipfile._strip_extra(a+a+a, (self.ZIP64_EXTRA,)))
3257+
self.assertEqual(
3258+
b"z", zipfile._strip_extra(a+a+b"z", (self.ZIP64_EXTRA,)))
3259+
self.assertEqual(
3260+
b+b"z", zipfile._strip_extra(a+a+b+b"z", (self.ZIP64_EXTRA,)))
3261+
3262+
self.assertEqual(b, zipfile._strip_extra(a+a+b, (self.ZIP64_EXTRA,)))
3263+
self.assertEqual(b, zipfile._strip_extra(a+b+a, (self.ZIP64_EXTRA,)))
3264+
self.assertEqual(b, zipfile._strip_extra(b+a+a, (self.ZIP64_EXTRA,)))
3265+
3266+
def test_too_short(self):
3267+
self.assertEqual(b"", zipfile._strip_extra(b"", (self.ZIP64_EXTRA,)))
3268+
self.assertEqual(b"z", zipfile._strip_extra(b"z", (self.ZIP64_EXTRA,)))
3269+
self.assertEqual(
3270+
b"zz", zipfile._strip_extra(b"zz", (self.ZIP64_EXTRA,)))
3271+
self.assertEqual(
3272+
b"zzz", zipfile._strip_extra(b"zzz", (self.ZIP64_EXTRA,)))
3273+
3274+
32133275
if __name__ == "__main__":
32143276
unittest.main()

Lib/zipfile.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,8 @@ def _strip_extra(extra, xids):
185185
i = j
186186
if not modified:
187187
return extra
188+
if start != len(extra):
189+
buffer.append(extra[start:])
188190
return b''.join(buffer)
189191

190192
def _check_zipfile(fp):
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Correctly preserve "extra" fields in ``zipfile`` regardless of their
2+
ordering relative to a zip64 "extra."

0 commit comments

Comments
 (0)
0