Skip to content

Commit 80a2413

Browse files
committed
Optimize _Extra and add tests
1 parent 0e5796f commit 80a2413

2 files changed

Lines changed: 51 additions & 32 deletions

File tree

Lib/test/test_zipfile/test_core.py

Lines changed: 49 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4114,6 +4114,16 @@ def test_read_zipfile_error(self):
41144114
with self.assertRaises(zipfile.BadZipfile):
41154115
zipfile.ZipFile(TESTFN, "r").close()
41164116

4117+
def test_read_zipfile_with_corrupted_extra_field(self):
4118+
with zipfile.ZipFile(TESTFN, mode='w') as zf:
4119+
zinfo = zipfile.ZipInfo("file.txt")
4120+
zinfo.extra = struct.pack('<HH', 1, 1)
4121+
zf.writestr(zinfo, b'_')
4122+
4123+
with self.assertRaisesRegex(zipfile.BadZipFile, 'Corrupt extra field 0001'):
4124+
with zipfile.ZipFile(TESTFN) as zf:
4125+
pass
4126+
41174127
def test_read_after_write_unicode_filenames(self):
41184128
with zipfile.ZipFile(TESTFN2, 'w') as zipfp:
41194129
zipfp.writestr('приклад', b'sample')
@@ -5840,59 +5850,69 @@ class StripExtraTests(unittest.TestCase):
58405850

58415851
ZIP64_EXTRA = 1
58425852

5853+
strip_extra = staticmethod(zipfile._Extra.strip)
5854+
58435855
def test_no_data(self):
58445856
s = struct.Struct("<HH")
58455857
a = s.pack(self.ZIP64_EXTRA, 0)
58465858
b = s.pack(2, 0)
58475859
c = s.pack(3, 0)
58485860

5849-
self.assertEqual(b'', zipfile._Extra.strip(a, (self.ZIP64_EXTRA,)))
5850-
self.assertEqual(b, zipfile._Extra.strip(b, (self.ZIP64_EXTRA,)))
5851-
self.assertEqual(
5852-
b+b"z", zipfile._Extra.strip(b+b"z", (self.ZIP64_EXTRA,)))
5861+
self.assertEqual(b'', self.strip_extra(a, (self.ZIP64_EXTRA,)))
5862+
self.assertEqual(b, self.strip_extra(b, (self.ZIP64_EXTRA,)))
5863+
self.assertEqual(b+b"z", self.strip_extra(b+b"z", (self.ZIP64_EXTRA,)))
58535864

5854-
self.assertEqual(b+c, zipfile._Extra.strip(a+b+c, (self.ZIP64_EXTRA,)))
5855-
self.assertEqual(b+c, zipfile._Extra.strip(b+a+c, (self.ZIP64_EXTRA,)))
5856-
self.assertEqual(b+c, zipfile._Extra.strip(b+c+a, (self.ZIP64_EXTRA,)))
5865+
self.assertEqual(b+c, self.strip_extra(a+b+c, (self.ZIP64_EXTRA,)))
5866+
self.assertEqual(b+c, self.strip_extra(b+a+c, (self.ZIP64_EXTRA,)))
5867+
self.assertEqual(b+c, self.strip_extra(b+c+a, (self.ZIP64_EXTRA,)))
58575868

58585869
def test_with_data(self):
58595870
s = struct.Struct("<HH")
58605871
a = s.pack(self.ZIP64_EXTRA, 1) + b"a"
58615872
b = s.pack(2, 2) + b"bb"
58625873
c = s.pack(3, 3) + b"ccc"
58635874

5864-
self.assertEqual(b"", zipfile._Extra.strip(a, (self.ZIP64_EXTRA,)))
5865-
self.assertEqual(b, zipfile._Extra.strip(b, (self.ZIP64_EXTRA,)))
5866-
self.assertEqual(
5867-
b+b"z", zipfile._Extra.strip(b+b"z", (self.ZIP64_EXTRA,)))
5875+
self.assertEqual(b"", self.strip_extra(a, (self.ZIP64_EXTRA,)))
5876+
self.assertEqual(b, self.strip_extra(b, (self.ZIP64_EXTRA,)))
5877+
self.assertEqual(b+b"z", self.strip_extra(b+b"z", (self.ZIP64_EXTRA,)))
58685878

5869-
self.assertEqual(b+c, zipfile._Extra.strip(a+b+c, (self.ZIP64_EXTRA,)))
5870-
self.assertEqual(b+c, zipfile._Extra.strip(b+a+c, (self.ZIP64_EXTRA,)))
5871-
self.assertEqual(b+c, zipfile._Extra.strip(b+c+a, (self.ZIP64_EXTRA,)))
5879+
self.assertEqual(b+c, self.strip_extra(a+b+c, (self.ZIP64_EXTRA,)))
5880+
self.assertEqual(b+c, self.strip_extra(b+a+c, (self.ZIP64_EXTRA,)))
5881+
self.assertEqual(b+c, self.strip_extra(b+c+a, (self.ZIP64_EXTRA,)))
58725882

58735883
def test_multiples(self):
58745884
s = struct.Struct("<HH")
58755885
a = s.pack(self.ZIP64_EXTRA, 1) + b"a"
58765886
b = s.pack(2, 2) + b"bb"
58775887

5878-
self.assertEqual(b"", zipfile._Extra.strip(a+a, (self.ZIP64_EXTRA,)))
5879-
self.assertEqual(b"", zipfile._Extra.strip(a+a+a, (self.ZIP64_EXTRA,)))
5880-
self.assertEqual(
5881-
b"z", zipfile._Extra.strip(a+a+b"z", (self.ZIP64_EXTRA,)))
5882-
self.assertEqual(
5883-
b+b"z", zipfile._Extra.strip(a+a+b+b"z", (self.ZIP64_EXTRA,)))
5888+
self.assertEqual(b"", self.strip_extra(a+a, (self.ZIP64_EXTRA,)))
5889+
self.assertEqual(b"", self.strip_extra(a+a+a, (self.ZIP64_EXTRA,)))
5890+
self.assertEqual(b"z", self.strip_extra(a+a+b"z", (self.ZIP64_EXTRA,)))
5891+
self.assertEqual(b+b"z", self.strip_extra(a+a+b+b"z", (self.ZIP64_EXTRA,)))
58845892

5885-
self.assertEqual(b, zipfile._Extra.strip(a+a+b, (self.ZIP64_EXTRA,)))
5886-
self.assertEqual(b, zipfile._Extra.strip(a+b+a, (self.ZIP64_EXTRA,)))
5887-
self.assertEqual(b, zipfile._Extra.strip(b+a+a, (self.ZIP64_EXTRA,)))
5893+
self.assertEqual(b, self.strip_extra(a+a+b, (self.ZIP64_EXTRA,)))
5894+
self.assertEqual(b, self.strip_extra(a+b+a, (self.ZIP64_EXTRA,)))
5895+
self.assertEqual(b, self.strip_extra(b+a+a, (self.ZIP64_EXTRA,)))
5896+
5897+
def test_truncated_data_for_stripped_id(self):
5898+
s = struct.Struct("<HH")
5899+
a = s.pack(self.ZIP64_EXTRA, 3) + b"a"
5900+
b = s.pack(2, 2) + b"bb"
5901+
5902+
self.assertEqual(b, self.strip_extra(b+a, (self.ZIP64_EXTRA,)))
5903+
5904+
def test_truncated_data_for_nonstripped_id(self):
5905+
s = struct.Struct("<HH")
5906+
a = s.pack(self.ZIP64_EXTRA, 1) + b"a"
5907+
b = s.pack(2, 4) + b"bb"
5908+
5909+
self.assertEqual(b, self.strip_extra(a+b, (self.ZIP64_EXTRA,)))
58885910

58895911
def test_too_short(self):
5890-
self.assertEqual(b"", zipfile._Extra.strip(b"", (self.ZIP64_EXTRA,)))
5891-
self.assertEqual(b"z", zipfile._Extra.strip(b"z", (self.ZIP64_EXTRA,)))
5892-
self.assertEqual(
5893-
b"zz", zipfile._Extra.strip(b"zz", (self.ZIP64_EXTRA,)))
5894-
self.assertEqual(
5895-
b"zzz", zipfile._Extra.strip(b"zzz", (self.ZIP64_EXTRA,)))
5912+
self.assertEqual(b"", self.strip_extra(b"", (self.ZIP64_EXTRA,)))
5913+
self.assertEqual(b"z", self.strip_extra(b"z", (self.ZIP64_EXTRA,)))
5914+
self.assertEqual(b"zz", self.strip_extra(b"zz", (self.ZIP64_EXTRA,)))
5915+
self.assertEqual(b"zzz", self.strip_extra(b"zzz", (self.ZIP64_EXTRA,)))
58965916

58975917

58985918
class StatIO(_pyio.BytesIO):

Lib/zipfile/__init__.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -207,10 +207,9 @@ def __init__(self, val, id=None):
207207
@classmethod
208208
def read_one(cls, raw):
209209
try:
210-
xid, xlen = cls.FIELD_STRUCT.unpack(raw[:4])
210+
xid, xlen = cls.FIELD_STRUCT.unpack_from(raw)
211211
except struct.error:
212-
xid = None
213-
xlen = 0
212+
xid, xlen = None, 0
214213
return cls(raw[:4+xlen], xid), raw[4+xlen:]
215214

216215
@classmethod

0 commit comments

Comments
 (0)