use image::{io::Limits, AnimationDecoder, ImageDecoder, ImageResult};
#[cfg(feature = "gif")]
use image::codecs::gif::GifDecoder;
#[cfg(feature = "gif")]
fn gif_decode(data: &[u8], limits: Limits) -> ImageResult<()> {
let mut decoder = GifDecoder::new(data).unwrap();
decoder.set_limits(limits)?;
{
let frames = decoder.into_frames();
for result in frames {
result?;
}
}
Ok(())
}
#[track_caller]
fn assert_limit_error(res: ImageResult<()>) {
let err = res.expect_err("The input should have been rejected because it exceeds limits");
match err {
image::ImageError::Limits(_) => (), _ => panic!("Decoding failed due to an error unrelated to limits"),
}
}
#[test]
#[cfg(feature = "gif")]
fn animated_full_frame_discard() {
let data =
std::fs::read("tests/images/gif/anim/large-gif-anim-full-frame-replace.gif").unwrap();
let mut limits_dimensions_too_small = Limits::default();
limits_dimensions_too_small.max_image_width = Some(500);
limits_dimensions_too_small.max_image_height = Some(500);
assert_limit_error(gif_decode(&data, limits_dimensions_too_small));
let mut limits_memory_way_too_small = Limits::default();
limits_memory_way_too_small.max_alloc = Some(5);
assert_limit_error(gif_decode(&data, limits_memory_way_too_small));
let mut limits_memory_too_small = Limits::default();
limits_memory_too_small.max_alloc = Some(1000 * 1000 * 5);
assert_limit_error(gif_decode(&data, limits_memory_too_small));
let mut limits_just_enough = Limits::default();
limits_just_enough.max_image_height = Some(1000);
limits_just_enough.max_image_width = Some(1000);
limits_just_enough.max_alloc = Some(1000 * 1000 * 4 * 2);
gif_decode(&data, limits_just_enough)
.expect("With these limits it should have decoded successfully");
}
#[test]
#[cfg(feature = "gif")]
fn animated_frame_combine() {
let data = std::fs::read("tests/images/gif/anim/large-gif-anim-combine.gif").unwrap();
let mut limits_dimensions_too_small = Limits::default();
limits_dimensions_too_small.max_image_width = Some(500);
limits_dimensions_too_small.max_image_height = Some(500);
assert_limit_error(gif_decode(&data, limits_dimensions_too_small));
let mut limits_memory_way_too_small = Limits::default();
limits_memory_way_too_small.max_alloc = Some(5);
assert_limit_error(gif_decode(&data, limits_memory_way_too_small));
let mut limits_memory_too_small = Limits::default();
limits_memory_too_small.max_alloc = Some(1000 * 1000 * 4 * 2); assert_limit_error(gif_decode(&data, limits_memory_too_small));
let mut limits_enough = Limits::default();
limits_enough.max_image_height = Some(1000);
limits_enough.max_image_width = Some(1000);
limits_enough.max_alloc = Some(1000 * 1000 * 4 * 3);
gif_decode(&data, limits_enough)
.expect("With these limits it should have decoded successfully");
}