diff --git a/Tests/LibGfx/TestImageDecoder.cpp b/Tests/LibGfx/TestImageDecoder.cpp index fdc76d228c..725c6b06f5 100644 --- a/Tests/LibGfx/TestImageDecoder.cpp +++ b/Tests/LibGfx/TestImageDecoder.cpp @@ -721,6 +721,20 @@ TEST_CASE(test_everything_tvg) } } +TEST_CASE(test_tvg_malformed) +{ + Array test_inputs = { + TEST_INPUT("tvg/bogus-color-table-size.tvg"sv) + }; + + for (auto test_input : test_inputs) { + auto file = MUST(Core::MappedFile::map(test_input)); + auto plugin_decoder = TRY_OR_FAIL(Gfx::TinyVGImageDecoderPlugin::create(file->bytes())); + auto frame_or_error = plugin_decoder->frame(0); + EXPECT(frame_or_error.is_error()); + } +} + TEST_CASE(test_jxl_modular_simple_tree_upsample2_10bits) { auto file = MUST(Core::MappedFile::map(TEST_INPUT("jxl/modular_simple_tree_upsample2_10bits_rct.jxl"sv))); diff --git a/Tests/LibGfx/test-inputs/tvg/bogus-color-table-size.tvg b/Tests/LibGfx/test-inputs/tvg/bogus-color-table-size.tvg new file mode 100644 index 0000000000..6ddcb94227 Binary files /dev/null and b/Tests/LibGfx/test-inputs/tvg/bogus-color-table-size.tvg differ diff --git a/Userland/Libraries/LibGfx/ImageFormats/TinyVGLoader.cpp b/Userland/Libraries/LibGfx/ImageFormats/TinyVGLoader.cpp index cff49dac2a..ec295a7a14 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/TinyVGLoader.cpp +++ b/Userland/Libraries/LibGfx/ImageFormats/TinyVGLoader.cpp @@ -127,11 +127,14 @@ static ErrorOr decode_tinyvg_header(Stream& stream) return header; } -static ErrorOr> decode_color_table(Stream& stream, ColorEncoding encoding, u32 color_count) +static ErrorOr> decode_color_table(Stream& stream, ColorEncoding encoding, u32 color_count) { if (encoding == ColorEncoding::Custom) return Error::from_string_literal("Invalid TinyVG: Unsupported color encoding"); - auto color_table = TRY(FixedArray::create(color_count)); + + static constexpr size_t MAX_INITIAL_COLOR_TABLE_SIZE = 65536; + Vector color_table; + TRY(color_table.try_ensure_capacity(min(MAX_INITIAL_COLOR_TABLE_SIZE, color_count))); auto parse_color = [&]() -> ErrorOr { switch (encoding) { case ColorEncoding::RGBA8888: { @@ -157,8 +160,8 @@ static ErrorOr> decode_color_table(Stream& stream, ColorEncodi return Error::from_string_literal("Invalid TinyVG: Bad color encoding"); } }; - for (auto& color : color_table) { - color = TRY(parse_color()); + while (color_count-- > 0) { + TRY(color_table.try_append(TRY(parse_color()))); } return color_table; } @@ -357,7 +360,7 @@ ErrorOr> TinyVGDecodedImageData::decode(St if (header.version != 1) return Error::from_string_literal("Invalid TinyVG: Unsupported version"); - auto color_table = TRY(decode_color_table(stream, header.color_encoding, header.color_count)); + auto const& color_table = TRY(decode_color_table(stream, header.color_encoding, header.color_count)); TinyVGReader reader { stream, header, color_table.span() }; auto rectangle_to_path = [](FloatRect const& rect) -> Path {