@@ -1136,6 +1136,54 @@ def test_bad_zip64_end_of_central_dir(self):
11361136 zipfile .ZipFile (io .BytesIO (zipdata ))
11371137 self .assertFalse (zipfile .is_zipfile (io .BytesIO (zipdata )))
11381138
1139+ def test_multi_disk_zip64_end_of_central_dir (self ):
1140+ zipdata = self .make_zip64_file ()
1141+ eocd64 = zipdata .rfind (zipfile .stringEndArchive64 )
1142+ disk_fields_offset = eocd64 + struct .calcsize ('<4sQ2H' )
1143+
1144+ for disk_number , disk_start in ((1 , 0 ), (0 , 1 ), (1 , 1 )):
1145+ corrupted = bytearray (zipdata )
1146+ struct .pack_into (
1147+ '<LL' , corrupted , disk_fields_offset ,
1148+ disk_number , disk_start ,
1149+ )
1150+ with self .subTest (
1151+ disk_number = disk_number ,
1152+ disk_start = disk_start ,
1153+ ):
1154+ with self .assertRaisesRegex (zipfile .BadZipFile ,
1155+ 'multiple disks' ):
1156+ zipfile .ZipFile (io .BytesIO (corrupted ))
1157+ self .assertFalse (zipfile .is_zipfile (io .BytesIO (corrupted )))
1158+
1159+ def test_multi_disk_end_of_central_dir_with_zip64 (self ):
1160+ zipdata = self .make_zip64_file ()
1161+ eocd = zipdata .rfind (zipfile .stringEndArchive )
1162+
1163+ for disk_number , disk_start in ((1 , 0 ), (0 , 1 ), (1 , 1 )):
1164+ corrupted = bytearray (zipdata )
1165+ struct .pack_into (
1166+ '<HH' , corrupted , eocd + 4 ,
1167+ disk_number , disk_start ,
1168+ )
1169+ with self .subTest (
1170+ disk_number = disk_number ,
1171+ disk_start = disk_start ,
1172+ ):
1173+ with self .assertRaisesRegex (zipfile .BadZipFile ,
1174+ 'multiple disks' ):
1175+ zipfile .ZipFile (io .BytesIO (corrupted ))
1176+ self .assertFalse (zipfile .is_zipfile (io .BytesIO (corrupted )))
1177+
1178+ def test_zip64_end_of_central_dir_disk_sentinels (self ):
1179+ zipdata = bytearray (self .make_zip64_file ())
1180+ eocd = zipdata .rfind (zipfile .stringEndArchive )
1181+ struct .pack_into ('<HH' , zipdata , eocd + 4 , 0xffff , 0xffff )
1182+
1183+ with zipfile .ZipFile (io .BytesIO (zipdata )) as zf :
1184+ self .assertEqual (zf .namelist (), ['test.txt' ])
1185+ self .assertTrue (zipfile .is_zipfile (io .BytesIO (zipdata )))
1186+
11391187 def test_zip64_end_of_central_dir_record_not_found (self ):
11401188 zipdata = self .make_zip64_file ()
11411189 zipdata = zipdata .replace (b"PK\x06 \x06 " , b'\x00 ' * 4 )
@@ -4246,6 +4294,34 @@ def test_damaged_zipfile(self):
42464294 fp = io .BytesIO (zipfiledata [:N ])
42474295 self .assertRaises (zipfile .BadZipFile , zipfile .ZipFile , fp )
42484296
4297+ def test_multi_disk_end_of_central_dir (self ):
4298+ for comment in (b'' , b'comment' ):
4299+ archive = io .BytesIO ()
4300+ with zipfile .ZipFile (archive , 'w' ) as zf :
4301+ zf .writestr ('entry.txt' , b'payload' )
4302+ zf .comment = comment
4303+ zipdata = archive .getvalue ()
4304+ eocd = zipdata .rfind (zipfile .stringEndArchive )
4305+
4306+ for disk_number , disk_start in ((1 , 0 ), (0 , 1 ), (1 , 1 )):
4307+ corrupted = bytearray (zipdata )
4308+ struct .pack_into (
4309+ '<HH' , corrupted , eocd + 4 ,
4310+ disk_number , disk_start ,
4311+ )
4312+ with self .subTest (
4313+ comment = comment ,
4314+ disk_number = disk_number ,
4315+ disk_start = disk_start ,
4316+ ):
4317+ with self .assertRaisesRegex (zipfile .BadZipFile ,
4318+ 'multiple disks' ):
4319+ zipfile .ZipFile (io .BytesIO (corrupted ))
4320+ fp = io .BytesIO (corrupted )
4321+ pos = fp .seek (5 )
4322+ self .assertFalse (zipfile .is_zipfile (fp ))
4323+ self .assertEqual (fp .tell (), pos )
4324+
42494325 def test_is_zip_valid_file (self ):
42504326 """Check that is_zipfile() correctly identifies zip files."""
42514327 # - passing a filename
0 commit comments