8000 [3.10] gh-88233: zipfile: handle extras after a zip64 extra (GH-96161… · python/cpython@d445147 · GitHub
[go: up one dir, main page]

Skip to content

Commit d445147

Browse files
10000
[3.10] gh-88233: zipfile: handle extras after a zip64 extra (GH-96161) (#102087)
Previously, any data _after_ the zip64 extra would be removed. With many new tests. Fixes GH-88233 (cherry picked from commit 59e86ca) Co-authored-by: Tim Hatch <tim@timhatch.com>
1 parent 3288923 commit d445147

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
@@ -3221,5 +3221,67 @@ def test_extract_orig_with_implied_dirs(self, alpharep):
32213221
zf.extractall(source_path.parent)
32223222

32233223

3224+
class StripExtraTests(unittest.TestCase):
3225+
# Note: all of the "z" characters are technically invalid, but up
3226+
# to 3 bytes at the end of the extra will be passed through as they
3227+
# are too short to encode a valid extra.
3228+
3229+
ZIP64_EXTRA = 1
3230+
3231+
def test_no_data(self):
3232+
s = struct.Struct("<HH")
3233+
a = s.pack(self.ZIP64_EXTRA, 0)
3234+
b = s.pack(2, 0)
3235+
c = s.pack(3, 0)
3236+
3237+
self.assertEqual(b'', zipfile._strip_extra(a, (self.ZIP64_EXTRA,)))
3238+
self.assertEqual(b, zipfile._strip_extra(b, (self.ZIP64_EXTRA,)))
3239+
self.assertEqual(
3240+
b+b"z", zipfile._strip_extra(b+b"z", (self.ZIP64_EXTRA,)))
3241+
3242+
self.assertEqual(b+c, zipfile._strip_extra(a+b+c, (self.ZIP64_EXTRA,)))
3243+
self.assertEqual(b+c, zipfile._strip_extra(b+a+c, (self.ZIP64_EXTRA,)))
3244+
self.assertEqual(b+c, zipfile._strip_extra(b+c+a, (self.ZIP64_EXTRA,)))
3245+
3246+
def test_with_data(self):
3247+
s = struct.Struct("<HH")
3248+
a = s.pack(self.ZIP64_EXTRA, 1) + b"a"
3249+
b = s.pack(2, 2) + b"bb"
3250+
c = s.pack(3, 3) + b"ccc"
3251+
3252+
self.assertEqual(b"", zipfile._strip_extra(a, (self.ZIP64_EXTRA,)))
3253+
self.assertEqual(b, zipfile._strip_extra(b, (self.ZIP64_EXTRA,)))
3254+
self.assertEqual(
3255+
b+b"z", zipfile._strip_extra(b+b"z", (self.ZIP64_EXTRA,)))
3256+
3257+
self.assertEqual(b+c, zipfile._strip_extra(a+b+c, (self.ZIP64_EXTRA,)))
3258+
self.assertEqual(b+c, zipfile._strip_extra(b+a+c, (self.ZIP64_EXTRA,)))
3259+
self.assertEqual(b+c, zipfile._strip_extra(b+c+a, (self.ZIP64_EXTRA,)))
3260+
3261+
def test_multiples(self):
3262+
s = struct.Struct("<HH")
3263+
a = s.pack(self.ZIP64_EXTRA, 1) + b"a"
3264+
b = s.pack(2, 2) + b"bb"
3265+
3266+
self.assertEqual(b"", zipfile._strip_extra(a+a, (self.ZIP64_EXTRA,)))
3267+
self.assertEqual(b"", zipfile._strip_extra(a+a+a, (self.ZIP64_EXTRA,)))
3268+
self.assertEqual(
3269+
b"z", zipfile._strip_extra(a+a+b"z", (self.ZIP64_EXTRA,)))
3270+
self.assertEqual(
3271+
b+b"z", zipfile._strip_extra(a+a+b+b"z", (self.ZIP64_EXTRA,)))
3272+
3273+
self.assertEqual(b, zipfile._strip_extra(a+a+b, (self.ZIP64_EXTRA,)))
3274+
self.assertEqual(b, zipfile._strip_extra(a+b+a, (self.ZIP64_EXTRA,)))
3275+
self.assertEqual(b, zipfile._strip_extra(b+a+a, (self.ZIP64_EXTRA,)))
3276+
3277+
def test_too_short(self):
3278+
self.assertEqual(b"", zipfile._strip_extra(b"", (self.ZIP64_EXTRA,)))
3279+
self.assertEqual(b"z", zipfile._strip_extra(b"z", (self.ZIP64_EXTRA,)))
3280+
self.assertEqual(
3281+
b"zz", zipfile._strip_extra(b"zz", (self.ZIP64_EXTRA,)))
3282+
self.assertEqual(
3283+
b"zzz", zipfile._strip_extra(b"zzz", (self.ZIP64_EXTRA,)))
3284+
3285+
32243286
if __name__ == "__main__":
32253287
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 + 40BC 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