From 21ff795071aae70847a0edeb045c1f9a37e61dc3 Mon Sep 17 00:00:00 2001 From: Chris Hennick Date: Sun, 14 May 2023 08:28:52 -0700 Subject: [PATCH] Additional sanity checks on ZIP64 footer --- src/read.rs | 12 ++++++++++++ src/write.rs | 14 ++++++++++++++ tests/data/zip64_magic_in_filename_5.zip | Bin 0 -> 562 bytes 3 files changed, 26 insertions(+) create mode 100644 tests/data/zip64_magic_in_filename_5.zip diff --git a/src/read.rs b/src/read.rs index 7efd1f9a..1c2faca2 100644 --- a/src/read.rs +++ b/src/read.rs @@ -356,6 +356,17 @@ impl ZipArchive { "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. diff --git a/src/write.rs b/src/write.rs index 1bdfb6be..98629dea 100644 --- a/src/write.rs +++ b/src/write.rs @@ -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"))] diff --git a/tests/data/zip64_magic_in_filename_5.zip b/tests/data/zip64_magic_in_filename_5.zip new file mode 100644 index 0000000000000000000000000000000000000000..bf6a95dbac040e2131ed1b112125c66bcb74cb33 GIT binary patch literal 562 zcmWIWW@Zs#U|`^2SY5d;49H+$0ueyK0>lB{Y;4Rx5|