diff --git a/Tests/LibGfx/TestImageDecoder.cpp b/Tests/LibGfx/TestImageDecoder.cpp index e309bd6ec36..0a72e09ad99 100644 --- a/Tests/LibGfx/TestImageDecoder.cpp +++ b/Tests/LibGfx/TestImageDecoder.cpp @@ -546,6 +546,18 @@ TEST_CASE(test_tiff_16_bits) EXPECT_EQ(frame.image->get_pixel(60, 75), Gfx::Color::NamedColor::Red); } +TEST_CASE(test_tiff_invalid_tag) +{ + auto file = MUST(Core::MappedFile::map(TEST_INPUT("tiff/invalid_tag.tiff"sv))); + EXPECT(Gfx::TIFFImageDecoderPlugin::sniff(file->bytes())); + auto plugin_decoder = TRY_OR_FAIL(Gfx::TIFFImageDecoderPlugin::create(file->bytes())); + + auto frame = TRY_OR_FAIL(expect_single_frame_of_size(*plugin_decoder, { 10, 10 })); + + EXPECT_EQ(frame.image->get_pixel(0, 0), Gfx::Color::NamedColor::Black); + EXPECT_EQ(frame.image->get_pixel(0, 9), Gfx::Color::NamedColor::White); +} + TEST_CASE(test_webp_simple_lossy) { auto file = MUST(Core::MappedFile::map(TEST_INPUT("webp/simple-vp8.webp"sv))); diff --git a/Tests/LibGfx/test-inputs/tiff/invalid_tag.tiff b/Tests/LibGfx/test-inputs/tiff/invalid_tag.tiff new file mode 100644 index 00000000000..501070fb1ae Binary files /dev/null and b/Tests/LibGfx/test-inputs/tiff/invalid_tag.tiff differ diff --git a/Userland/Libraries/LibGfx/ImageFormats/TIFFLoader.cpp b/Userland/Libraries/LibGfx/ImageFormats/TIFFLoader.cpp index acdd3029d7b..4cb4ca7ac2b 100644 --- a/Userland/Libraries/LibGfx/ImageFormats/TIFFLoader.cpp +++ b/Userland/Libraries/LibGfx/ImageFormats/TIFFLoader.cpp @@ -387,9 +387,18 @@ private: TRY(m_stream->seek(m_next_ifd.value())); auto const number_of_field = TRY(read_value()); + auto next_tag_offset = TRY(m_stream->tell()); - for (u16 i = 0; i < number_of_field; ++i) - TRY(read_tag()); + for (u16 i = 0; i < number_of_field; ++i) { + TRY(m_stream->seek(next_tag_offset)); + if (auto maybe_error = read_tag(); maybe_error.is_error() && TIFF_DEBUG) + dbgln("Unable to decode tag {}/{}", i + 1, number_of_field); + + // Section 2: TIFF Structure + // IFD Entry + // Size of tag(u16) + type(u16) + count(u32) + value_or_offset(u32) = 12 + next_tag_offset += 12; + } TRY(read_next_idf_offset()); return {};