mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-10-29 12:38:58 -06:00
fix(create): decode an indexed lookup table within a small cap
Image export decoded a stream lookup table under the general 1 GiB stream limit although a table holds at most 1024 bytes, and every image sharing the palette decoded it again. The table now decodes within 64 KiB and a larger one is refused for that image.
This commit is contained in:
@@ -359,6 +359,9 @@ impl Space {
|
||||
}
|
||||
}
|
||||
|
||||
/// A lookup table holds at most 256 entries of 4 bytes; decoding stops well past that.
|
||||
const MAX_LOOKUP: usize = 64 << 10;
|
||||
|
||||
fn space(doc: &Document, cs: Option<&Object>) -> Result<Space, String> {
|
||||
let Some(cs) = cs else { return Err("the image has no colour space".into()) };
|
||||
let cs = doc.resolve(cs);
|
||||
@@ -393,7 +396,9 @@ fn space(doc: &Document, cs: Option<&Object>) -> Result<Space, String> {
|
||||
};
|
||||
let table = match a.get(3).map(|t| doc.resolve(t)).as_deref() {
|
||||
Some(Object::String(s)) => s.bytes.clone(),
|
||||
Some(Object::Stream(t)) => t.decoded().map_err(|e| e.to_string())?,
|
||||
Some(Object::Stream(t)) => {
|
||||
t.decoded_within(MAX_LOOKUP).map_err(|_| "an indexed colour space with an oversized or damaged lookup table".to_string())?
|
||||
}
|
||||
_ => return Err("an indexed colour space without a lookup table".into()),
|
||||
};
|
||||
Ok(Space::Indexed(Box::new(base), hival, table))
|
||||
|
||||
@@ -832,6 +832,15 @@ fn indexed_hival_resolves_indirect_values_and_stream_palettes() {
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn indexed_lookup_stream_has_a_size_cap() {
|
||||
// A lookup table needs 256 × 4 bytes at most; a 1 MiB one is refused, not decoded whole.
|
||||
let mut palette = vec![255, 0, 0, 0, 0, 255];
|
||||
palette.resize(1 << 20, 0);
|
||||
let (doc, image) = indexed_export_fixture(Object::Int(1), palette, true, false, 8, vec![0, 1, 0, 1]);
|
||||
assert!(crate::extract::image_file(&doc, image).unwrap_err().contains("lookup table"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn indexed_hival_boundary_values_keep_valid_palette_entries() {
|
||||
let palette: Vec<u8> = (0..=255u8).flat_map(|i| [i, 255 - i, 17]).collect();
|
||||
|
||||
Reference in New Issue
Block a user