mirror of
https://github.com/storytold/designcraft.git
synced 2026-11-14 14:22:39 +00:00
Format: a failed entry read counts against the archive budget
* format: bytes a failed entry read inflated count against the archive budget * address review: mutate the payload bytes explicitly in the checksum test * address review: charge a failed read to the budget it belongs to (stored vs deflated)
This commit is contained in:
1 parent
26d5c8941c
commit
665fe2a8e4
2 files changed
+28
-2
No files matched your search
@@ -224,10 +224,17 @@ fn read_entry(
|
||||
return Err(too_big());
|
||||
}
|
||||
let mut v = Vec::new();
|
||||
if f.take(limit.saturating_add(1)).read_to_end(&mut v).is_err() {
|
||||
let read = f.take(limit.saturating_add(1)).read_to_end(&mut v);
|
||||
let n = v.len() as u64;
|
||||
// What a failed read produced was inflated all the same: it counts against the archive's budget.
|
||||
if read.is_err() {
|
||||
if stored {
|
||||
*stored_left = stored_left.saturating_sub(n);
|
||||
} else {
|
||||
*left = left.saturating_sub(n);
|
||||
}
|
||||
return Ok(None);
|
||||
}
|
||||
let n = v.len() as u64;
|
||||
if n > limit {
|
||||
return Err(too_big());
|
||||
}
|
||||
|
||||
@@ -3,6 +3,25 @@ use designcraft_doc::build::NewDocument;
|
||||
use designcraft_doc::geom::Rect;
|
||||
use designcraft_doc::{Asset, ParaFormat, SpreadRef};
|
||||
|
||||
/// An entry that fails after inflating (a bad checksum) still uses up the archive's byte budget.
|
||||
#[test]
|
||||
fn a_failed_read_is_charged_to_the_budget() {
|
||||
let mut z = zip::ZipWriter::new(Cursor::new(Vec::new()));
|
||||
let stored = zip::write::SimpleFileOptions::default().compression_method(zip::CompressionMethod::Stored);
|
||||
z.start_file("a", stored).unwrap();
|
||||
z.write_all(&[7u8; 1000]).unwrap();
|
||||
let mut bytes = z.finish().unwrap().into_inner();
|
||||
// Flip a data byte: the entry reads in full, then fails its checksum.
|
||||
// The payload is the only run of 1,000 consecutive 7s in the archive.
|
||||
let start = bytes.windows(1000).position(|w| w.iter().all(|b| *b == 7)).expect("payload");
|
||||
bytes[start] = 8;
|
||||
let mut archive = zip::ZipArchive::new(Cursor::new(bytes.as_slice())).unwrap();
|
||||
let (mut left, mut stored_left) = (5000, 5000);
|
||||
assert_eq!(read_entry(&mut archive, "a", 4000, &mut left, &mut stored_left).unwrap(), None);
|
||||
// A failed stored read is charged to the stored budget only.
|
||||
assert_eq!((left, stored_left), (5000, 4000));
|
||||
}
|
||||
|
||||
fn png_asset(d: &mut Document, data: &[u8]) -> AssetId {
|
||||
let aid = AssetId(d.alloc());
|
||||
let a =
|
||||
|
||||
Reference in new issue
Block a user