Additional sanity checks on ZIP64 footer

This commit is contained in:
Chris Hennick 2023-05-14 08:28:52 -07:00
parent e35a4ee938
commit 21ff795071
No known key found for this signature in database
GPG key ID: 25653935CC8B6C74
3 changed files with 26 additions and 0 deletions

View file

@ -356,6 +356,17 @@ impl<R: Read + Seek> ZipArchive<R> {
"Invalid central directory size or offset",
));
}
if footer64.number_of_files_on_this_disk > footer64.number_of_files {
return Err(ZipError::InvalidArchive(
"ZIP64 footer indicates more files on this disk than in the whole archive"
));
}
if footer64.version_needed_to_extract > footer64.version_made_by {
return Err(ZipError::InvalidArchive(
"ZIP64 footer indicates a new version is needed to extract this archive than the \
version that wrote it"
));
}
let supported = if (footer64.disk_number != footer64.disk_with_central_directory)
|| (!footer.record_too_small()
@ -1266,6 +1277,7 @@ mod test {
include_bytes!("../tests/data/zip64_magic_in_filename_2.zip").to_vec(),
include_bytes!("../tests/data/zip64_magic_in_filename_3.zip").to_vec(),
include_bytes!("../tests/data/zip64_magic_in_filename_4.zip").to_vec(),
include_bytes!("../tests/data/zip64_magic_in_filename_5.zip").to_vec(),
];
// Although we don't allow adding files whose names contain the ZIP64 CDB-end or
// CDB-end-locator signatures, we still read them when they aren't genuinely ambiguous.

View file

@ -1701,6 +1701,20 @@ mod test {
println!("{:02x?}", zip.get_ref());
let _ = ZipArchive::new(zip).unwrap();
}
#[test]
fn test_filename_looks_like_zip64_locator_4() {
let mut writer = ZipWriter::new(io::Cursor::new(Vec::new()));
writer.start_file("PK\u{6}\u{6}", FileOptions::default()).unwrap();
writer.start_file("\0\0\0\0\0\0", FileOptions::default()).unwrap();
writer.start_file("\0", FileOptions::default()).unwrap();
writer.start_file("", FileOptions::default()).unwrap();
writer.start_file("\0\0", FileOptions::default()).unwrap();
writer.start_file("\0\0\0PK\u{6}\u{7}\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", FileOptions::default()).unwrap();
let zip = writer.finish().unwrap();
println!("{:02x?}", zip.get_ref());
let _ = ZipArchive::new(zip).unwrap();
}
}
#[cfg(not(feature = "unreserved"))]

Binary file not shown.