From 44a26f4b930ba05fb64bc1835bedac19b83640eb Mon Sep 17 00:00:00 2001 From: "Dylan M. Taylor" Date: Mon, 9 Nov 2026 05:36:19 -0500 Subject: [PATCH] fix(model,oracle): read a page box only when it has four entries; skip empty images (#5941) --- crates/model/src/lib.rs | 8 ++++++-- crates/oracle/src/pixels.rs | 12 ++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/crates/model/src/lib.rs b/crates/model/src/lib.rs index 94da24ea1c..23eede9b45 100644 --- a/crates/model/src/lib.rs +++ b/crates/model/src/lib.rs @@ -24,8 +24,12 @@ const MIN_BOX_SIDE: f64 = 1.0 / 4096.0; fn rect(doc: &Document, o: Option<&Object>) -> Option<[f64; 4]> { let o = doc.resolve(o?); - let v: Vec = o.as_array()?.iter().filter_map(|x| doc.resolve(x).as_f64()).collect(); - (v.len() == 4 && v.iter().all(|x| x.is_finite())).then(|| [v[0].min(v[2]), v[1].min(v[3]), v[0].max(v[2]), v[1].max(v[3])]) + // Four entries, or not a rectangle: a longer array (one shared by many pages, say) is not + // resolved entry by entry only to be discarded. + let [a, b, c, d] = o.as_array()?.as_slice() else { return None }; + let v = [a, b, c, d].map(|x| doc.resolve(x).as_f64()); + let [Some(x0), Some(y0), Some(x1), Some(y1)] = v else { return None }; + [x0, y0, x1, y1].iter().all(|x| x.is_finite()).then(|| [x0.min(x1), y0.min(y1), x0.max(x1), y0.max(y1)]) } impl Page { diff --git a/crates/oracle/src/pixels.rs b/crates/oracle/src/pixels.rs index 4ff0ebaf13..6681aaa5df 100644 --- a/crates/oracle/src/pixels.rs +++ b/crates/oracle/src/pixels.rs @@ -105,6 +105,10 @@ pub fn compare(a: Gray<'_>, b: Gray<'_>, tolerance: u8) -> Result, b: Gray<'_>, tolerance: u8) -> usize { + // No pixels, nothing to match: a zero-width image of enormous height is not walked row by row. + if a.pixels.is_empty() { + return 0; + } let mut count = 0usize; for y in 0..a.height { for x in 0..a.width { @@ -210,6 +214,14 @@ fn find(haystack: &[u8], needle: &[u8]) -> Option { #[cfg(test)] mod tests { + /// A zero-width image of enormous height has no pixels to walk. + #[test] + fn an_image_without_pixels_compares_at_once() { + let a = Gray { width: 0, height: usize::MAX, pixels: &[] }; + let d = compare(a, a, 0).unwrap(); + assert_eq!((d.differing, d.total), (0, 0)); + } + use super::*; fn gray(w: usize, h: usize, fill: u8) -> Vec {