use std::fs::File;
use std::io::Write;
use std::path::PathBuf;
use zip::write::SimpleFileOptions;
use zip::CompressionMethod;
use zip::ZipWriter;
use openpack::{Limits, OpenPack, OpenPackError};
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_oom_massive_allocation_request() {
let archive = Scratch::new("zip");
let payload = b"small_payload";
write_zip(
&archive.path,
&[("payload.bin", payload, CompressionMethod::Stored)],
);
let mut limits = Limits::default();
limits.max_entry_uncompressed_size = 1;
let pack = OpenPack::open(&archive.path, limits).unwrap();
let result = pack.read_entry("payload.bin");
assert!(
matches!(result, Err(OpenPackError::LimitExceeded(_))),
"Expected OOM protection (LimitExceeded) for massive allocation request relative to limit, got {:?}", result
);
}