diff --git a/crates/ui-egui/src/menus/clipboard.rs b/crates/ui-egui/src/menus/clipboard.rs index ff065a48f..bae7aaca9 100644 --- a/crates/ui-egui/src/menus/clipboard.rs +++ b/crates/ui-egui/src/menus/clipboard.rs @@ -129,9 +129,6 @@ fn clipboard_png(app: &mut FigApp) -> Option<(Vec, f64, f64)> { Some(readable) => readable, None => with_pixel_size(encoded_clipboard_image(app)?)?, }; - if w == 0 || h == 0 || u64::from(w) * u64::from(h) > MAX_PASTED_IMAGE_PIXELS { - return None; - } let density = figcraft_format::pixel_density(&png); let (w, h) = figcraft_format::placed_size(w, h, density, figcraft_engine::cmd::create::PLACED_IMAGE_MAX_SIDE); Some((png, w, h)) @@ -140,8 +137,14 @@ fn clipboard_png(app: &mut FigApp) -> Option<(Vec, f64, f64)> { const MAX_PASTED_IMAGE_PIXELS: u64 = 100_000_000; fn with_pixel_size(png: Vec) -> Option<(Vec, (u32, u32))> { - let size = image::ImageReader::new(std::io::Cursor::new(&png)).with_guessed_format().ok()?.into_dimensions().ok()?; - Some((png, size)) + use image::ImageDecoder as _; + let decoder = image::ImageReader::new(std::io::Cursor::new(&png)).with_guessed_format().ok()?.into_decoder().ok()?; + let (w, h) = decoder.dimensions(); + if w == 0 || h == 0 || u64::from(w) * u64::from(h) > MAX_PASTED_IMAGE_PIXELS { + return None; + } + image::DynamicImage::from_decoder(decoder).ok()?; + Some((png, (w, h))) } fn encoded_clipboard_image(app: &mut FigApp) -> Option> { diff --git a/crates/ui-egui/src/paste_image_tests.rs b/crates/ui-egui/src/paste_image_tests.rs index e70ea0968..756c93067 100644 --- a/crates/ui-egui/src/paste_image_tests.rs +++ b/crates/ui-egui/src/paste_image_tests.rs @@ -549,3 +549,18 @@ fn a_clipboard_png_past_the_byte_limit_falls_back_to_the_decoded_image() { let pasted = doc.nodes().find(|n| n.name == "Pasted image").expect("pasted from the decoded image"); assert_eq!((pasted.width, pasted.height), (2.0, 2.0)); } + +#[test] +fn a_clipboard_png_with_a_cut_off_body_falls_back_to_the_decoded_image() { + let mut w = Win::new(); + let mut png = std::io::Cursor::new(Vec::new()); + image::RgbaImage::new(4, 4).write_to(&mut png, image::ImageFormat::Png).unwrap(); + let png = png.into_inner(); + let cut_off = png[..png.len() - 20].to_vec(); + assert_eq!(image::ImageReader::new(std::io::Cursor::new(&cut_off)).with_guessed_format().unwrap().into_dimensions().unwrap(), (4, 4)); + *w.clip.borrow_mut() = Clip { png: Some(cut_off), image: Some((2, 2, vec![255; 16])), ..Clip::default() }; + w.cmd_v(); + let doc = w.app.session.doc().unwrap(); + let pasted = doc.nodes().find(|n| n.name == "Pasted image").expect("pasted from the decoded image"); + assert_eq!((pasted.width, pasted.height), (2.0, 2.0)); +}