-
Notifications
You must be signed in to change notification settings - Fork 597
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Panic when an animated webp image is loaded #1775
Comments
I have a similar but subtley different issue (running v0.24.4, but it looks like this still applies to the patch above). The reproduction steps are the same, but I think it's specific to animated webps with no transparency such as this example: I get the following panic:
The slice lengths looked suspiciously like it's trying to copy RGB values into an RGBA buffer and panicking because the lengths don't match. Inspecting the header with webpinfo, the VP8X header has Alpha set to true but the actual frames all have it set to false.
I ran a debugger and it seems like the codec reads the VP8X header and assumes the frames have an alpha channel, but the frames encode that individually. If I set a breakpoint here and set info.alpha to false, everything works as expected. |
diff --git a/src/codecs/webp/extended.rs b/src/codecs/webp/extended.rs
index 8ae61a9..a7868d9 100644
--- a/src/codecs/webp/extended.rs
+++ b/src/codecs/webp/extended.rs
@@ -249,14 +249,20 @@ impl ExtendedImage {
anim_image: &AnimatedFrame,
background_color: Rgba<u8>,
) -> Option<ImageResult<Frame>> {
- let mut buffer = vec![0; (anim_image.width * anim_image.height * 4) as usize];
+ let mut buffer = vec![0; anim_image.image.get_buf_size()];
anim_image.image.fill_buf(&mut buffer);
+ let has_alpha = match &anim_image.image {
+ WebPStatic::LossyWithAlpha(..) => true,
+ WebPStatic::LossyWithoutAlpha(..) => false,
+ WebPStatic::Lossless(..) => true,
+ };
+ let pixel_len = if has_alpha { 4 } else { 3 };
for x in 0..anim_image.width {
for y in 0..anim_image.height {
let canvas_index: (u32, u32) = (x + anim_image.offset_x, y + anim_image.offset_y);
- let index: usize = (y * 4 * anim_image.width + x * 4).try_into().unwrap();
- canvas[canvas_index] = if anim_image.use_alpha_blending {
+ let index: usize = ((y * anim_image.width + x) * pixel_len).try_into().unwrap();
+ canvas[canvas_index] = if anim_image.use_alpha_blending && has_alpha {
let buffer: [u8; 4] = buffer[index..][..4].try_into().unwrap();
ExtendedImage::do_alpha_blending(buffer, canvas[canvas_index])
} else {
@@ -264,7 +270,7 @@ impl ExtendedImage {
buffer[index],
buffer[index + 1],
buffer[index + 2],
- buffer[index + 3],
+ if has_alpha { buffer[index + 3] } else { 255 },
])
};
} |
I'm running into this with 0.24.5. I can see that this is fixed in your main line. Is there an ETA for making a release with this fix? |
Use mainline image crate to avoid an otherwise unavoidable panic in the upstream: image-rs/image#1775 Explicitly operate on the frames from the animation. refs: #3250
Thanks for the reminder. I'll try to get out a release this weekend |
This happens in BoilR
PhilipK/BoilR#203
Whenever an animated webp image is loaded it will lead to a panic:
Expected
Expected the image to load a static image, or just give an Result::Error instead of panic
Actual behaviour
A panic is thrown
Reproduction steps
Download an animated image, eaxmple: https://cdn2.steamgriddb.com/file/sgdb-cdn/logo/42cd4e870371f116e5695912004e1b5a.webp
Load the image with the following code:
The code will now panic
The text was updated successfully, but these errors were encountered: