From ab029e1b533bb1081b335ebd715cc664aadcecf5 Mon Sep 17 00:00:00 2001 From: dotCooCoo Date: Sun, 8 Nov 2026 14:44:42 -0800 Subject: [PATCH] Plug-ins: an image too large to count its pixels comes without them An image object whose width times height overflows is given with pixelsOmitted instead of overflowing the size check. --- crates/plugins/src/objects.rs | 4 ++-- crates/plugins/src/objects/tests.rs | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/crates/plugins/src/objects.rs b/crates/plugins/src/objects.rs index 17d7c1e19..3f572e0b8 100644 --- a/crates/plugins/src/objects.rs +++ b/crates/plugins/src/objects.rs @@ -421,8 +421,8 @@ fn color_mode(b: &ImageBlob) -> &'static str { /// The pixels of image `b` as straight RGBA, when it is `w` × `h` pixels and they fit `max` /// characters of base64; the size is checked, and read from the header, before anything is decoded. fn rgba_pixels(b: &ImageBlob, w: u32, h: u32, max: usize) -> Option> { - let bytes = u64::from(w) * u64::from(h) * 4; - if bytes == 0 || bytes.div_ceil(3) * 4 > max as u64 { + let bytes = u64::from(w).checked_mul(u64::from(h))?.checked_mul(4)?; + if bytes == 0 || bytes.div_ceil(3).saturating_mul(4) > max as u64 { return None; } if b.is_cmyk() { diff --git a/crates/plugins/src/objects/tests.rs b/crates/plugins/src/objects/tests.rs index d421f98dc..85778552b 100644 --- a/crates/plugins/src/objects/tests.rs +++ b/crates/plugins/src/objects/tests.rs @@ -447,6 +447,10 @@ fn declared_embedded_and_linked_images_have_distinct_metadata_and_pixel_omission let n = image_node(&mut d, "e", (3, 1), None); let id = d.insert(Some(layer), usize::MAX, n).unwrap(); assert_eq!(encode_read_only(&d, d.node(id).unwrap()).unwrap()["pixelsOmitted"], json!(true), "not the size it says"); + // A size whose pixel count overflows is omitted too. + let n = image_node(&mut d, "e", (u32::MAX, u32::MAX), None); + let id = d.insert(Some(layer), usize::MAX, n).unwrap(); + assert_eq!(encode_read_only(&d, d.node(id).unwrap()).unwrap()["pixelsOmitted"], json!(true), "too large to count"); // Gray pixels, and data that isn't an image. let mut gray = vec![]; image::GrayImage::from_pixel(2, 2, image::Luma([90])).write_to(&mut std::io::Cursor::new(&mut gray), image::ImageFormat::Png).unwrap();