@@ -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
35223557class PyZipFileTests (unittest .TestCase ):
35233558 def assertCompiledIn (self , name , namelist ):
0 commit comments