From 0805319d1e6a831c49e0718a7d33392112d7ec3d Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Tue, 7 May 2024 18:00:33 -0400 Subject: [PATCH] LibGfx/WebPLoader: Diagnose mismatch between VP8X and VP8L alpha bits If this turns out to be too strict in practice, we can replace it with a `dbgln("VP8X and VP8L headers disagree about alpha; ignoring VP8X");` instead. ALso update catdog-alert-13-alpha-used-false.webp to not trigger this. I had manually changed the VP8L alpha flag at offset 0x2a in da48238fbdf4158 to clear it, but I hadn't changed the VP8X flag. This changes the byte at offset 0x14 from 0x10 (has_alpha) to 0x00 (no alpha) as well, to match. --- .../webp/catdog-alert-13-alpha-used-false.webp | Bin 400 -> 400 bytes .../LibGfx/ImageFormats/WebPLoader.cpp | 10 +++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Tests/LibGfx/test-inputs/webp/catdog-alert-13-alpha-used-false.webp b/Tests/LibGfx/test-inputs/webp/catdog-alert-13-alpha-used-false.webp index 991a5ffae328ebff0b7720e29d9f7f4c90f8b2b9..49939b59f9583498fbbdb736771df1ed7b665ee8 100644 GIT binary patch delta 12 TcmbQhJb`(F2qVKr(P~Bj6|@5m delta 12 TcmbQhJb`(F2&2G8(P~Bj76bzx diff --git a/Userland/Libraries/LibGfx/ImageFormats/WebPLoader.cpp b/Userland/Libraries/LibGfx/ImageFormats/WebPLoader.cpp index c1caac03bf6..e7b1eb1d1f2 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/WebPLoader.cpp +++ b/Userland/Libraries/LibGfx/ImageFormats/WebPLoader.cpp @@ -548,11 +548,15 @@ static ErrorOr decode_webp_animation_frame_image_data(ANMFChunk const return decode_webp_set_image_data(move(alpha), move(image_data)); } -static ErrorOr> decode_webp_image_data(ImageData const& image_data) +static ErrorOr> decode_webp_image_data(WebPLoadingContext& context, ImageData const& image_data) { if (image_data.image_data_chunk.id() == "VP8L"sv) { VERIFY(!image_data.alpha_chunk.has_value()); auto vp8l_header = TRY(decode_webp_chunk_VP8L_header(image_data.image_data_chunk.data())); + + if (context.first_chunk->id() == "VP8X" && context.vp8x_header.has_alpha != vp8l_header.is_alpha_used) + return Error::from_string_literal("WebPImageDecoderPlugin: VP8X header alpha flag doesn't match VP8L header"); + return decode_webp_chunk_VP8L_contents(vp8l_header); } @@ -602,7 +606,7 @@ static ErrorOr decode_webp_animation_frame(WebPLoadingCont } auto frame_image_data = TRY(decode_webp_animation_frame_image_data(frame_description)); - auto frame_bitmap = TRY(decode_webp_image_data(frame_image_data)); + auto frame_bitmap = TRY(decode_webp_image_data(context, frame_image_data)); if (static_cast(frame_bitmap->width()) != frame_description.frame_width || static_cast(frame_bitmap->height()) != frame_description.frame_height) return Error::from_string_literal("WebPImageDecoderPlugin: decoded frame bitmap size doesn't match frame description size"); @@ -714,7 +718,7 @@ ErrorOr WebPImageDecoderPlugin::frame(size_t index, Option } if (m_context->state < WebPLoadingContext::State::BitmapDecoded) { - auto bitmap = TRY(decode_webp_image_data(m_context->image_data.value())); + auto bitmap = TRY(decode_webp_image_data(*m_context, m_context->image_data.value())); // Check that size in VP8X chunk matches dimensions in VP8 or VP8L chunk if both are present. if (m_context->first_chunk->id() == "VP8X") {