use std::fs::File;
use std::io::Write;
use std::path::PathBuf;
use zip::write::SimpleFileOptions;
use zip::CompressionMethod;
use zip::ZipWriter;
use openpack::OpenPack;
struct Scratch {
_tmp: tempfile::TempDir,
path: PathBuf,
}
impl Scratch {
fn new(suffix: &str) -> Self {
let tmp = tempfile::tempdir().expect("tempdir");
let path = tmp.path().join(format!("archive.{suffix}"));
Self { _tmp: tmp, path }
}
}
fn write_zip(path: &std::path::Path, entries: &[(&str, &[u8], CompressionMethod)]) {
let file = File::create(path).unwrap();
let mut zip = ZipWriter::new(file);
for (name, data, comp) in entries {
let options = SimpleFileOptions::default().compression_method(*comp);
zip.start_file(*name, options).unwrap();
zip.write_all(data).unwrap();
}
zip.finish().unwrap();
}
#[test]
fn test_integer_overflow_u32_truncation_size() {
let archive = Scratch::new("zip");
let payload = vec![0x11; 256];
write_zip(
&archive.path,
&[("exact_256.bin", &payload, CompressionMethod::Stored)],
);
let pack = OpenPack::open_default(&archive.path).unwrap();
let content = pack.read_entry("exact_256.bin").unwrap();
assert_eq!(content.len(), 256);
}
#[test]
fn test_integer_overflow_pattern_counts() {
let archive = Scratch::new("zip");
let mut entries = Vec::new();
let content = b"data";
for i in 0..256 {
entries.push(format!("entry_{}.txt", i));
}
let file = File::create(&archive.path).unwrap();
let mut zip = ZipWriter::new(file);
let options = SimpleFileOptions::default().compression_method(CompressionMethod::Stored);
for name in &entries {
zip.start_file(name, options).unwrap();
zip.write_all(content).unwrap();
}
zip.finish().unwrap();
let pack = OpenPack::open_default(&archive.path).unwrap();
let listed = pack.entries().unwrap();
assert_eq!(listed.len(), 256, "Should list exactly 256 entries");
for i in 0..256 {
let name = format!("entry_{}.txt", i);
assert!(pack.contains(&name).unwrap(), "Missing entry {}", name);
}
}