Skip to content

Commit b70a80b

Browse files
committed
gh-51067: Add tests for entry-size overshoot and _copy_bytes EOF
Covers the new bounds check in _validate_local_file_entry and the short-read guard in _copy_bytes.
1 parent eb29a30 commit b70a80b

1 file changed

Lines changed: 35 additions & 0 deletions

File tree

Lib/test/test_zipfile/test_core.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2920,6 +2920,34 @@ def _test_validate_local_file_entry_zip64(self, method):
29202920
m_sddnsbd.assert_not_called()
29212921
m_sddns.assert_not_called()
29222922

2923+
def test_validate_local_file_entry_overshoot(self):
2924+
"""A header whose compress_size points past end_offset is rejected."""
2925+
repacker = zipfile._ZipRepacker()
2926+
2927+
bytes_ = self._generate_local_file_entry('file.txt', b'dummy')
2928+
fz = io.BytesIO(bytes_)
2929+
# exact fit at end_offset is accepted
2930+
self.assertEqual(
2931+
repacker._validate_local_file_entry(fz, 0, len(bytes_)),
2932+
len(bytes_),
2933+
)
2934+
# one byte short: entry would extend past end_offset
2935+
self.assertIsNone(
2936+
repacker._validate_local_file_entry(fz, 0, len(bytes_) - 1),
2937+
)
2938+
2939+
# zip64 extra supplying the oversized compress_size
2940+
bytes_ = self._generate_local_file_entry(
2941+
'file.txt', b'dummy', force_zip64=True)
2942+
fz = io.BytesIO(bytes_)
2943+
self.assertEqual(
2944+
repacker._validate_local_file_entry(fz, 0, len(bytes_)),
2945+
len(bytes_),
2946+
)
2947+
self.assertIsNone(
2948+
repacker._validate_local_file_entry(fz, 0, len(bytes_) - 1),
2949+
)
2950+
29232951
def test_validate_local_file_entry_encrypted(self):
29242952
# strict_descriptor=False to exercise unsigned data descriptor scanning
29252953
# of an encrypted entry (the default strict_descriptor=True is tested below)
@@ -3518,6 +3546,13 @@ def test_copy_bytes(self):
35183546
self.assertEqual(m_read.mock_calls, [
35193547
mock.call(1), mock.call(1), mock.call(1), mock.call(1), mock.call(1), mock.call(1)])
35203548

3549+
def test_copy_bytes_short_read(self):
3550+
"""Raise rather than loop forever if EOF is hit before size bytes."""
3551+
repacker = zipfile._ZipRepacker()
3552+
fp = io.BytesIO(b'abc123')
3553+
with self.assertRaises(zipfile.BadZipFile):
3554+
repacker._copy_bytes(fp, 0, 0, 100)
3555+
35213556

35223557
class PyZipFileTests(unittest.TestCase):
35233558
def assertCompiledIn(self, name, namelist):

0 commit comments

Comments
 (0)