From 24967b0d29fb4425a3604944544076fa6bd002cd Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Fri, 7 Apr 2023 15:18:39 -0400 Subject: [PATCH] LibGfx: Second attempt to handle max_symbol correctly in webp decoder The previous attempt was in commit e5e9d3b877c, where I thought max_symbol describes how many code lengths should be read. But it looks like it instead describes how many code length input symbols should be read. (The two aren't the same since one code length input symbol can produce several code lengths.) I still agree with the commit description of e5e9d3b877c that the spec isn't very clear on this :) This time I've found a file that sets max_symbol and with this change here, that file decodes correctly. (It's Qpalette.webp, which I'm about to add as a test case.) --- .../Libraries/LibGfx/ImageFormats/WebPLoader.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Userland/Libraries/LibGfx/ImageFormats/WebPLoader.cpp b/Userland/Libraries/LibGfx/ImageFormats/WebPLoader.cpp index 997b2d4b88..2219bb8df1 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/WebPLoader.cpp +++ b/Userland/Libraries/LibGfx/ImageFormats/WebPLoader.cpp @@ -438,8 +438,12 @@ static ErrorOr decode_webp_chunk_VP8L_prefix_code(WebPLoadingCont u8 last_non_zero = 8; // "If code 16 is used before a non-zero value has been emitted, a value of 8 is repeated." // "A prefix table is then built from code_length_code_lengths and used to read up to max_symbol code lengths." - dbgln_if(WEBP_DEBUG, " reading {} symbols", max_symbol); - while (code_lengths.size() < max_symbol) { + dbgln_if(WEBP_DEBUG, " reading {} symbols from at most {} codes", alphabet_size, max_symbol); + while (code_lengths.size() < alphabet_size) { + if (max_symbol == 0) + break; + --max_symbol; + auto symbol = TRY(code_length_code.read_symbol(bit_stream)); if (symbol < 16) { @@ -472,8 +476,8 @@ static ErrorOr decode_webp_chunk_VP8L_prefix_code(WebPLoadingCont } } - if (code_lengths.size() != alphabet_size) - return Error::from_string_literal("Number of code lengths does not match the sum of codes"); + if (code_lengths.size() > alphabet_size) + return Error::from_string_literal("Number of code lengths is larger than the alphabet size"); dbgln_if(WEBP_DEBUG, " done reading symbols"); return CanonicalCode::from_bytes(code_lengths);