From 3817a9f3ec116efbef494a74e02d188804e77ccd Mon Sep 17 00:00:00 2001 From: FredApps <153173854+FredApps@users.noreply.github.com> Date: Sun, 1 Nov 2026 12:08:33 +0100 Subject: [PATCH] refactor(engine): drop redundant image and font checks - page_image_at: PageImage::contains already requires the point inside visible_rect (rect clipped by the placement clip), so the extra bounds test before it decided nothing. - image_dimensions: the 256 MB input-length guard repeated the caller's; the decoder's max_alloc limit still caps what decoding allocates. Its test no longer allocates 256 MB to hit that guard. - font_content_key hashed every font file twice; one 64-bit hash plus the length is enough to tell duplicate files apart. Co-Authored-By: Claude Opus 5.5 --- crates/engine/src/copy_image.rs | 10 +--------- crates/engine/src/pictures.rs | 8 +------- crates/engine/src/text_fonts.rs | 11 ++++------- 3 files changed, 6 insertions(+), 23 deletions(-) diff --git a/crates/engine/src/copy_image.rs b/crates/engine/src/copy_image.rs index ab92bc738c..53b890f27c 100644 --- a/crates/engine/src/copy_image.rs +++ b/crates/engine/src/copy_image.rs @@ -18,16 +18,8 @@ impl Document { /// [`Document::page_images`]: a raster image, or Form artwork that holds one. pub fn page_image_at(&self, page: usize, at: [f64; 2]) -> Option { let editor = self.editor.as_ref()?; - let inside = |r: &[f64; 4]| (r[0]..=r[2]).contains(&at[0]) && (r[1]..=r[3]).contains(&at[1]); self.page_images(page).iter().rposition(|i| { - let bounds = if let Some(clip) = i.clip_rect { - let r = [i.rect[0].max(clip[0]), i.rect[1].max(clip[1]), i.rect[2].min(clip[2]), i.rect[3].min(clip[3])]; - if r.iter().all(|v| v.is_finite()) && r[2] > r[0] && r[3] > r[1] { r } else { i.visible_rect.unwrap_or(i.rect) } - } else { - i.visible_rect.unwrap_or(i.rect) - }; - inside(&bounds) - && i.contains(at) + i.contains(at) && match (i.is_form, i.object) { (false, Some(_)) => true, (true, Some(form)) => picture_in_form(&editor.cos, form).is_some(), diff --git a/crates/engine/src/pictures.rs b/crates/engine/src/pictures.rs index 48859bc524..49d76f07c0 100644 --- a/crates/engine/src/pictures.rs +++ b/crates/engine/src/pictures.rs @@ -62,9 +62,6 @@ pub(crate) fn mark_source(doc: &mut pdfcraft_cos::Document, f: &MarkFile) -> Res /// The dimensions of an image from its bytes (JPEG, PNG, TIFF), without decoding the full raster. pub fn image_dimensions(bytes: &[u8]) -> Option<(u32, u32)> { - if bytes.len() > 64_000_000 * 4 { - return None; - } let format = image::guess_format(bytes).ok()?; let mut reader = image::ImageReader::with_format(std::io::Cursor::new(bytes), format); let mut limits = image::Limits::default(); @@ -123,11 +120,8 @@ mod tests { } #[test] - fn invalid_and_oversized_inputs_return_none() { + fn invalid_inputs_return_none() { assert_eq!(image_dimensions(&[]), None); assert_eq!(image_dimensions(b"not an image"), None); - - let huge = vec![0u8; 64_000_000 * 4 + 1]; - assert_eq!(image_dimensions(&huge), None); } } diff --git a/crates/engine/src/text_fonts.rs b/crates/engine/src/text_fonts.rs index 5cc43c4081..ce8f169b74 100644 --- a/crates/engine/src/text_fonts.rs +++ b/crates/engine/src/text_fonts.rs @@ -89,14 +89,11 @@ pub fn discover_budgeted(roots: &[PathBuf], mut budget: u64) -> Vec { files } -fn font_content_key(bytes: &[u8]) -> (usize, u64, u64) { +fn font_content_key(bytes: &[u8]) -> (usize, u64) { use std::hash::{DefaultHasher, Hasher}; - let mut h1 = DefaultHasher::new(); - h1.write(bytes); - let mut h2 = DefaultHasher::new(); - h2.write_u8(0xff); - h2.write(bytes); - (bytes.len(), h1.finish(), h2.finish()) + let mut h = DefaultHasher::new(); + h.write(bytes); + (bytes.len(), h.finish()) } fn font_extension(path: &Path) -> bool { path.extension().and_then(std::ffi::OsStr::to_str).is_some_and(|e| e.eq_ignore_ascii_case("ttf") || e.eq_ignore_ascii_case("otf"))