LibGfx+Fuzz: Convert ImageDecoder::initialize to ErrorOr

This prevents callers from accidentally discarding the result of
initialize(), which was the root cause of this OSS Fuzz bug:

https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=55896&q=label%3AProj-serenity&sort=summary
This commit is contained in:
Ben Wiederhake 2023-05-07 19:27:07 +02:00 committed by Sam Atkins
parent a84e64ed22
commit da394abe04
37 changed files with 125 additions and 105 deletions

View file

@ -13,7 +13,8 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* data, size_t size)
if (decoder_or_error.is_error())
return 0;
auto decoder = decoder_or_error.release_value();
decoder->initialize();
(void)decoder->frame(0);
if (!decoder->initialize().is_error()) {
(void)decoder->frame(0);
}
return 0;
}

View file

@ -16,7 +16,9 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* data, size_t size)
if (decoder_or_error.is_error())
return 0;
auto decoder = decoder_or_error.release_value();
decoder->initialize();
if (decoder->initialize().is_error()) {
return 0;
}
auto& gif_decoder = *decoder;
auto bitmap_or_error = decoder->frame(0);
if (!bitmap_or_error.is_error()) {

View file

@ -14,7 +14,8 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* data, size_t size)
if (decoder_or_error.is_error())
return 0;
auto decoder = decoder_or_error.release_value();
decoder->initialize();
(void)decoder->frame(0);
if (!decoder->initialize().is_error()) {
(void)decoder->frame(0);
}
return 0;
}

View file

@ -14,7 +14,8 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* data, size_t size)
if (decoder_or_error.is_error())
return 0;
auto decoder = decoder_or_error.release_value();
decoder->initialize();
(void)decoder->frame(0);
if (!decoder->initialize().is_error()) {
(void)decoder->frame(0);
}
return 0;
}

View file

@ -14,7 +14,8 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* data, size_t size)
if (decoder_or_error.is_error())
return 0;
auto decoder = decoder_or_error.release_value();
decoder->initialize();
(void)decoder->frame(0);
if (!decoder->initialize().is_error()) {
(void)decoder->frame(0);
}
return 0;
}

View file

@ -14,7 +14,8 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* data, size_t size)
if (decoder_or_error.is_error())
return 0;
auto decoder = decoder_or_error.release_value();
decoder->initialize();
(void)decoder->frame(0);
if (!decoder->initialize().is_error()) {
(void)decoder->frame(0);
}
return 0;
}

View file

@ -14,7 +14,8 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* data, size_t size)
if (decoder_or_error.is_error())
return 0;
auto decoder = decoder_or_error.release_value();
decoder->initialize();
(void)decoder->frame(0);
if (!decoder->initialize().is_error()) {
(void)decoder->frame(0);
}
return 0;
}

View file

@ -14,7 +14,8 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* data, size_t size)
if (decoder_or_error.is_error())
return 0;
auto decoder = decoder_or_error.release_value();
decoder->initialize();
(void)decoder->frame(0);
if (!decoder->initialize().is_error()) {
(void)decoder->frame(0);
}
return 0;
}

View file

@ -14,7 +14,8 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* data, size_t size)
if (decoder_or_error.is_error())
return 0;
auto decoder = decoder_or_error.release_value();
decoder->initialize();
(void)decoder->frame(0);
if (!decoder->initialize().is_error()) {
(void)decoder->frame(0);
}
return 0;
}

View file

@ -14,7 +14,8 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* data, size_t size)
if (decoder_or_error.is_error())
return 0;
auto decoder = decoder_or_error.release_value();
decoder->initialize();
(void)decoder->frame(0);
if (!decoder->initialize().is_error()) {
(void)decoder->frame(0);
}
return 0;
}

View file

@ -14,7 +14,8 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t const* data, size_t size)
if (decoder_or_error.is_error())
return 0;
auto decoder = decoder_or_error.release_value();
decoder->initialize();
(void)decoder->frame(0);
if (!decoder->initialize().is_error()) {
(void)decoder->frame(0);
}
return 0;
}

View file

@ -24,7 +24,7 @@ TEST_CASE(png)
{
auto file = MUST(Core::MappedFile::map(TEST_INPUT("icc-v2.png"sv)));
auto png = MUST(Gfx::PNGImageDecoderPlugin::create(file->bytes()));
EXPECT(png->initialize());
MUST(png->initialize());
auto icc_bytes = MUST(png->icc_data());
EXPECT(icc_bytes.has_value());
@ -36,7 +36,7 @@ TEST_CASE(jpg)
{
auto file = MUST(Core::MappedFile::map(TEST_INPUT("icc-v4.jpg"sv)));
auto jpg = MUST(Gfx::JPEGImageDecoderPlugin::create(file->bytes()));
EXPECT(jpg->initialize());
MUST(jpg->initialize());
auto icc_bytes = MUST(jpg->icc_data());
EXPECT(icc_bytes.has_value());
@ -48,7 +48,7 @@ TEST_CASE(webp_extended_lossless)
{
auto file = MUST(Core::MappedFile::map(TEST_INPUT("extended-lossless.webp"sv)));
auto webp = MUST(Gfx::WebPImageDecoderPlugin::create(file->bytes()));
EXPECT(webp->initialize());
MUST(webp->initialize());
auto icc_bytes = MUST(webp->icc_data());
EXPECT(icc_bytes.has_value());
@ -60,7 +60,7 @@ TEST_CASE(webp_extended_lossy)
{
auto file = MUST(Core::MappedFile::map(TEST_INPUT("extended-lossy.webp"sv)));
auto webp = MUST(Gfx::WebPImageDecoderPlugin::create(file->bytes()));
EXPECT(webp->initialize());
MUST(webp->initialize());
auto icc_bytes = MUST(webp->icc_data());
EXPECT(icc_bytes.has_value());

View file

@ -33,7 +33,7 @@ TEST_CASE(test_bmp)
auto file = MUST(Core::MappedFile::map(TEST_INPUT("rgba32-1.bmp"sv)));
EXPECT(Gfx::BMPImageDecoderPlugin::sniff(file->bytes()));
auto plugin_decoder = MUST(Gfx::BMPImageDecoderPlugin::create(file->bytes()));
EXPECT(plugin_decoder->initialize());
MUST(plugin_decoder->initialize());
EXPECT(plugin_decoder->frame_count());
EXPECT(!plugin_decoder->is_animated());
@ -48,7 +48,7 @@ TEST_CASE(test_gif)
auto file = MUST(Core::MappedFile::map(TEST_INPUT("download-animation.gif"sv)));
EXPECT(Gfx::GIFImageDecoderPlugin::sniff(file->bytes()));
auto plugin_decoder = MUST(Gfx::GIFImageDecoderPlugin::create(file->bytes()));
EXPECT(plugin_decoder->initialize());
MUST(plugin_decoder->initialize());
EXPECT(plugin_decoder->frame_count());
EXPECT(plugin_decoder->is_animated());
@ -63,7 +63,7 @@ TEST_CASE(test_not_ico)
auto file = MUST(Core::MappedFile::map(TEST_INPUT("buggie.png"sv)));
EXPECT(!Gfx::ICOImageDecoderPlugin::sniff(file->bytes()));
auto plugin_decoder = MUST(Gfx::ICOImageDecoderPlugin::create(file->bytes()));
EXPECT(!plugin_decoder->initialize());
EXPECT(plugin_decoder->initialize().is_error());
EXPECT(plugin_decoder->frame_count());
EXPECT(!plugin_decoder->is_animated());
@ -77,13 +77,13 @@ TEST_CASE(test_bmp_embedded_in_ico)
auto file = MUST(Core::MappedFile::map(TEST_INPUT("serenity.ico"sv)));
EXPECT(Gfx::ICOImageDecoderPlugin::sniff(file->bytes()));
auto plugin_decoder = MUST(Gfx::ICOImageDecoderPlugin::create(file->bytes()));
EXPECT(plugin_decoder->initialize());
MUST(plugin_decoder->initialize());
EXPECT(plugin_decoder->frame_count());
EXPECT(!plugin_decoder->is_animated());
EXPECT(!plugin_decoder->loop_count());
EXPECT(!plugin_decoder->frame(0).is_error());
MUST(plugin_decoder->frame(0));
}
TEST_CASE(test_jpeg_sof0_one_scan)
@ -91,7 +91,7 @@ TEST_CASE(test_jpeg_sof0_one_scan)
auto file = MUST(Core::MappedFile::map(TEST_INPUT("rgb24.jpg"sv)));
EXPECT(Gfx::JPEGImageDecoderPlugin::sniff(file->bytes()));
auto plugin_decoder = MUST(Gfx::JPEGImageDecoderPlugin::create(file->bytes()));
EXPECT(plugin_decoder->initialize());
MUST(plugin_decoder->initialize());
EXPECT(plugin_decoder->frame_count());
EXPECT(!plugin_decoder->is_animated());
@ -106,7 +106,7 @@ TEST_CASE(test_jpeg_sof0_several_scans)
auto file = MUST(Core::MappedFile::map(TEST_INPUT("several_scans.jpg"sv)));
EXPECT(Gfx::JPEGImageDecoderPlugin::sniff(file->bytes()));
auto plugin_decoder = MUST(Gfx::JPEGImageDecoderPlugin::create(file->bytes()));
EXPECT(plugin_decoder->initialize());
MUST(plugin_decoder->initialize());
auto frame = MUST(plugin_decoder->frame(0));
EXPECT_EQ(frame.image->size(), Gfx::IntSize(592, 800));
@ -117,7 +117,7 @@ TEST_CASE(test_jpeg_rgb_components)
auto file = MUST(Core::MappedFile::map(TEST_INPUT("rgb_components.jpg"sv)));
EXPECT(Gfx::JPEGImageDecoderPlugin::sniff(file->bytes()));
auto plugin_decoder = MUST(Gfx::JPEGImageDecoderPlugin::create(file->bytes()));
EXPECT(plugin_decoder->initialize());
MUST(plugin_decoder->initialize());
auto frame = MUST(plugin_decoder->frame(0));
EXPECT_EQ(frame.image->size(), Gfx::IntSize(592, 800));
@ -128,7 +128,7 @@ TEST_CASE(test_jpeg_sof2_spectral_selection)
auto file = MUST(Core::MappedFile::map(TEST_INPUT("spectral_selection.jpg"sv)));
EXPECT(Gfx::JPEGImageDecoderPlugin::sniff(file->bytes()));
auto plugin_decoder = MUST(Gfx::JPEGImageDecoderPlugin::create(file->bytes()));
EXPECT(plugin_decoder->initialize());
MUST(plugin_decoder->initialize());
auto frame = MUST(plugin_decoder->frame(0));
EXPECT_EQ(frame.image->size(), Gfx::IntSize(592, 800));
@ -139,7 +139,7 @@ TEST_CASE(test_jpeg_sof0_several_scans_odd_number_mcu)
auto file = MUST(Core::MappedFile::map(TEST_INPUT("several_scans_odd_number_mcu.jpg"sv)));
EXPECT(Gfx::JPEGImageDecoderPlugin::sniff(file->bytes()));
auto plugin_decoder = MUST(Gfx::JPEGImageDecoderPlugin::create(file->bytes()));
EXPECT(plugin_decoder->initialize());
MUST(plugin_decoder->initialize());
auto frame = MUST(plugin_decoder->frame(0));
EXPECT_EQ(frame.image->size(), Gfx::IntSize(600, 600));
@ -150,7 +150,7 @@ TEST_CASE(test_jpeg_sof2_successive_aproximation)
auto file = MUST(Core::MappedFile::map(TEST_INPUT("successive_approximation.jpg"sv)));
EXPECT(Gfx::JPEGImageDecoderPlugin::sniff(file->bytes()));
auto plugin_decoder = MUST(Gfx::JPEGImageDecoderPlugin::create(file->bytes()));
EXPECT(plugin_decoder->initialize());
MUST(plugin_decoder->initialize());
auto frame = MUST(plugin_decoder->frame(0));
EXPECT_EQ(frame.image->size(), Gfx::IntSize(600, 800));
@ -161,7 +161,7 @@ TEST_CASE(test_jpeg_sof1_12bits)
auto file = MUST(Core::MappedFile::map(TEST_INPUT("12-bit.jpg"sv)));
EXPECT(Gfx::JPEGImageDecoderPlugin::sniff(file->bytes()));
auto plugin_decoder = MUST(Gfx::JPEGImageDecoderPlugin::create(file->bytes()));
EXPECT(plugin_decoder->initialize());
MUST(plugin_decoder->initialize());
auto frame = MUST(plugin_decoder->frame(0));
EXPECT_EQ(frame.image->size(), Gfx::IntSize(320, 240));
@ -172,7 +172,7 @@ TEST_CASE(test_jpeg_sof2_12bits)
auto file = MUST(Core::MappedFile::map(TEST_INPUT("12-bit-progressive.jpg"sv)));
EXPECT(Gfx::JPEGImageDecoderPlugin::sniff(file->bytes()));
auto plugin_decoder = MUST(Gfx::JPEGImageDecoderPlugin::create(file->bytes()));
EXPECT(plugin_decoder->initialize());
MUST(plugin_decoder->initialize());
auto frame = MUST(plugin_decoder->frame(0));
EXPECT_EQ(frame.image->size(), Gfx::IntSize(320, 240));
@ -183,7 +183,7 @@ TEST_CASE(test_pbm)
auto file = MUST(Core::MappedFile::map(TEST_INPUT("buggie-raw.pbm"sv)));
EXPECT(Gfx::PBMImageDecoderPlugin::sniff(file->bytes()));
auto plugin_decoder = MUST(Gfx::PBMImageDecoderPlugin::create(file->bytes()));
EXPECT(plugin_decoder->initialize());
MUST(plugin_decoder->initialize());
EXPECT(plugin_decoder->frame_count());
EXPECT(!plugin_decoder->is_animated());
@ -198,7 +198,7 @@ TEST_CASE(test_pgm)
auto file = MUST(Core::MappedFile::map(TEST_INPUT("buggie-raw.pgm"sv)));
EXPECT(Gfx::PGMImageDecoderPlugin::sniff(file->bytes()));
auto plugin_decoder = MUST(Gfx::PGMImageDecoderPlugin::create(file->bytes()));
EXPECT(plugin_decoder->initialize());
MUST(plugin_decoder->initialize());
EXPECT(plugin_decoder->frame_count());
EXPECT(!plugin_decoder->is_animated());
@ -213,7 +213,7 @@ TEST_CASE(test_png)
auto file = MUST(Core::MappedFile::map(TEST_INPUT("buggie.png"sv)));
EXPECT(Gfx::PNGImageDecoderPlugin::sniff(file->bytes()));
auto plugin_decoder = MUST(Gfx::PNGImageDecoderPlugin::create(file->bytes()));
EXPECT(plugin_decoder->initialize());
MUST(plugin_decoder->initialize());
EXPECT(plugin_decoder->frame_count());
EXPECT(!plugin_decoder->is_animated());
@ -228,7 +228,7 @@ TEST_CASE(test_ppm)
auto file = MUST(Core::MappedFile::map(TEST_INPUT("buggie-raw.ppm"sv)));
EXPECT(Gfx::PPMImageDecoderPlugin::sniff(file->bytes()));
auto plugin_decoder = MUST(Gfx::PPMImageDecoderPlugin::create(file->bytes()));
EXPECT(plugin_decoder->initialize());
MUST(plugin_decoder->initialize());
EXPECT(plugin_decoder->frame_count());
EXPECT(!plugin_decoder->is_animated());
@ -243,7 +243,7 @@ TEST_CASE(test_targa_bottom_left)
auto file = MUST(Core::MappedFile::map(TEST_INPUT("buggie-bottom-left-uncompressed.tga"sv)));
EXPECT(MUST(Gfx::TGAImageDecoderPlugin::validate_before_create(file->bytes())));
auto plugin_decoder = MUST(Gfx::TGAImageDecoderPlugin::create(file->bytes()));
EXPECT(plugin_decoder->initialize());
MUST(plugin_decoder->initialize());
EXPECT_EQ(plugin_decoder->frame_count(), 1u);
EXPECT(!plugin_decoder->is_animated());
@ -258,7 +258,7 @@ TEST_CASE(test_targa_top_left)
auto file = MUST(Core::MappedFile::map(TEST_INPUT("buggie-top-left-uncompressed.tga"sv)));
EXPECT(MUST(Gfx::TGAImageDecoderPlugin::validate_before_create(file->bytes())));
auto plugin_decoder = MUST(Gfx::TGAImageDecoderPlugin::create(file->bytes()));
EXPECT(plugin_decoder->initialize());
MUST(plugin_decoder->initialize());
EXPECT_EQ(plugin_decoder->frame_count(), 1u);
EXPECT(!plugin_decoder->is_animated());
@ -273,7 +273,7 @@ TEST_CASE(test_targa_bottom_left_compressed)
auto file = MUST(Core::MappedFile::map(TEST_INPUT("buggie-bottom-left-compressed.tga"sv)));
EXPECT(MUST(Gfx::TGAImageDecoderPlugin::validate_before_create(file->bytes())));
auto plugin_decoder = MUST(Gfx::TGAImageDecoderPlugin::create(file->bytes()));
EXPECT(plugin_decoder->initialize());
MUST(plugin_decoder->initialize());
EXPECT_EQ(plugin_decoder->frame_count(), 1u);
EXPECT(!plugin_decoder->is_animated());
@ -288,7 +288,7 @@ TEST_CASE(test_targa_top_left_compressed)
auto file = MUST(Core::MappedFile::map(TEST_INPUT("buggie-top-left-compressed.tga"sv)));
EXPECT(MUST(Gfx::TGAImageDecoderPlugin::validate_before_create(file->bytes())));
auto plugin_decoder = MUST(Gfx::TGAImageDecoderPlugin::create(file->bytes()));
EXPECT(plugin_decoder->initialize());
MUST(plugin_decoder->initialize());
EXPECT_EQ(plugin_decoder->frame_count(), 1u);
EXPECT(!plugin_decoder->is_animated());
@ -303,7 +303,7 @@ TEST_CASE(test_webp_simple_lossy)
auto file = MUST(Core::MappedFile::map(TEST_INPUT("simple-vp8.webp"sv)));
EXPECT(Gfx::WebPImageDecoderPlugin::sniff(file->bytes()));
auto plugin_decoder = MUST(Gfx::WebPImageDecoderPlugin::create(file->bytes()));
EXPECT(plugin_decoder->initialize());
MUST(plugin_decoder->initialize());
EXPECT_EQ(plugin_decoder->frame_count(), 1u);
EXPECT(!plugin_decoder->is_animated());
@ -319,7 +319,7 @@ TEST_CASE(test_webp_simple_lossless)
auto file = MUST(Core::MappedFile::map(TEST_INPUT("simple-vp8l.webp"sv)));
EXPECT(Gfx::WebPImageDecoderPlugin::sniff(file->bytes()));
auto plugin_decoder = MUST(Gfx::WebPImageDecoderPlugin::create(file->bytes()));
EXPECT(plugin_decoder->initialize());
MUST(plugin_decoder->initialize());
EXPECT_EQ(plugin_decoder->frame_count(), 1u);
EXPECT(!plugin_decoder->is_animated());
@ -345,7 +345,7 @@ TEST_CASE(test_webp_extended_lossy)
auto file = MUST(Core::MappedFile::map(TEST_INPUT("extended-lossy.webp"sv)));
EXPECT(Gfx::WebPImageDecoderPlugin::sniff(file->bytes()));
auto plugin_decoder = MUST(Gfx::WebPImageDecoderPlugin::create(file->bytes()));
EXPECT(plugin_decoder->initialize());
MUST(plugin_decoder->initialize());
EXPECT_EQ(plugin_decoder->frame_count(), 1u);
EXPECT(!plugin_decoder->is_animated());
@ -361,7 +361,7 @@ TEST_CASE(test_webp_extended_lossless)
auto file = MUST(Core::MappedFile::map(TEST_INPUT("extended-lossless.webp"sv)));
EXPECT(Gfx::WebPImageDecoderPlugin::sniff(file->bytes()));
auto plugin_decoder = MUST(Gfx::WebPImageDecoderPlugin::create(file->bytes()));
EXPECT(plugin_decoder->initialize());
MUST(plugin_decoder->initialize());
EXPECT_EQ(plugin_decoder->frame_count(), 1u);
EXPECT(!plugin_decoder->is_animated());
@ -392,7 +392,7 @@ TEST_CASE(test_webp_simple_lossless_color_index_transform)
auto file = MUST(Core::MappedFile::map(TEST_INPUT("Qpalette.webp"sv)));
EXPECT(Gfx::WebPImageDecoderPlugin::sniff(file->bytes()));
auto plugin_decoder = MUST(Gfx::WebPImageDecoderPlugin::create(file->bytes()));
EXPECT(plugin_decoder->initialize());
MUST(plugin_decoder->initialize());
EXPECT_EQ(plugin_decoder->frame_count(), 1u);
EXPECT(!plugin_decoder->is_animated());
@ -429,7 +429,7 @@ TEST_CASE(test_webp_simple_lossless_color_index_transform_pixel_bundling)
auto file = MUST(Core::MappedFile::map(MUST(String::formatted("{}{}", TEST_INPUT(""), test_case.file_name))));
EXPECT(Gfx::WebPImageDecoderPlugin::sniff(file->bytes()));
auto plugin_decoder = MUST(Gfx::WebPImageDecoderPlugin::create(file->bytes()));
EXPECT(plugin_decoder->initialize());
MUST(plugin_decoder->initialize());
EXPECT_EQ(plugin_decoder->frame_count(), 1u);
EXPECT_EQ(plugin_decoder->size(), Gfx::IntSize(32, 32));
@ -457,7 +457,7 @@ TEST_CASE(test_webp_simple_lossless_color_index_transform_pixel_bundling_odd_wid
for (auto file_name : file_names) {
auto file = MUST(Core::MappedFile::map(MUST(String::formatted("{}{}", TEST_INPUT(""), file_name))));
auto plugin_decoder = MUST(Gfx::WebPImageDecoderPlugin::create(file->bytes()));
EXPECT(plugin_decoder->initialize());
MUST(plugin_decoder->initialize());
EXPECT_EQ(plugin_decoder->frame_count(), 1u);
EXPECT_EQ(plugin_decoder->size(), Gfx::IntSize(11, 11));
@ -472,7 +472,7 @@ TEST_CASE(test_webp_extended_lossless_animated)
auto file = MUST(Core::MappedFile::map(TEST_INPUT("extended-lossless-animated.webp"sv)));
EXPECT(Gfx::WebPImageDecoderPlugin::sniff(file->bytes()));
auto plugin_decoder = MUST(Gfx::WebPImageDecoderPlugin::create(file->bytes()));
EXPECT(plugin_decoder->initialize());
MUST(plugin_decoder->initialize());
EXPECT_EQ(plugin_decoder->frame_count(), 8u);
EXPECT(plugin_decoder->is_animated());

View file

@ -213,7 +213,7 @@ Icon FileIconProvider::icon_for_executable(DeprecatedString const& path)
// FIXME: Use the ImageDecoder service.
if (Gfx::PNGImageDecoderPlugin::sniff({ section->raw_data(), section->size() })) {
auto png_decoder = Gfx::PNGImageDecoderPlugin::create({ section->raw_data(), section->size() }).release_value_but_fixme_should_propagate_errors();
if (png_decoder->initialize()) {
if (!png_decoder->initialize().is_error()) {
auto frame_or_error = png_decoder->frame(0);
if (!frame_or_error.is_error()) {
bitmap = frame_or_error.value().image;

View file

@ -1501,9 +1501,9 @@ bool BMPImageDecoderPlugin::set_nonvolatile(bool& was_purged)
return m_context->bitmap->set_nonvolatile(was_purged);
}
bool BMPImageDecoderPlugin::initialize()
ErrorOr<void> BMPImageDecoderPlugin::initialize()
{
return !decode_bmp_header(*m_context).is_error();
return decode_bmp_header(*m_context);
}
bool BMPImageDecoderPlugin::sniff(ReadonlyBytes data)

View file

@ -30,7 +30,7 @@ public:
virtual IntSize size() override;
virtual void set_volatile() override;
[[nodiscard]] virtual bool set_nonvolatile(bool& was_purged) override;
virtual bool initialize() override;
virtual ErrorOr<void> initialize() override;
bool sniff_dib();
virtual bool is_animated() override;
virtual size_t loop_count() override;

View file

@ -645,14 +645,17 @@ bool DDSImageDecoderPlugin::set_nonvolatile(bool& was_purged)
return m_context->bitmap->set_nonvolatile(was_purged);
}
bool DDSImageDecoderPlugin::initialize()
ErrorOr<void> DDSImageDecoderPlugin::initialize()
{
// The header is always at least 128 bytes, so if the file is smaller, it can't be a DDS.
return m_context->data_size > 128
if (m_context->data_size > 128
&& m_context->data[0] == 0x44
&& m_context->data[1] == 0x44
&& m_context->data[2] == 0x53
&& m_context->data[3] == 0x20;
&& m_context->data[3] == 0x20)
return {};
return Error::from_string_literal("Bad image magic");
}
bool DDSImageDecoderPlugin::sniff(ReadonlyBytes data)

View file

@ -243,7 +243,7 @@ public:
virtual IntSize size() override;
virtual void set_volatile() override;
[[nodiscard]] virtual bool set_nonvolatile(bool& was_purged) override;
virtual bool initialize() override;
virtual ErrorOr<void> initialize() override;
virtual bool is_animated() override;
virtual size_t loop_count() override;
virtual size_t frame_count() override;

View file

@ -562,10 +562,11 @@ bool GIFImageDecoderPlugin::set_nonvolatile(bool& was_purged)
return m_context->frame_buffer->set_nonvolatile(was_purged);
}
bool GIFImageDecoderPlugin::initialize()
ErrorOr<void> GIFImageDecoderPlugin::initialize()
{
FixedMemoryStream stream { { m_context->data, m_context->data_size } };
return !decode_gif_header(stream).is_error();
TRY(decode_gif_header(stream));
return {};
}
bool GIFImageDecoderPlugin::sniff(ReadonlyBytes data)

View file

@ -23,7 +23,7 @@ public:
virtual IntSize size() override;
virtual void set_volatile() override;
[[nodiscard]] virtual bool set_nonvolatile(bool& was_purged) override;
virtual bool initialize() override;
virtual ErrorOr<void> initialize() override;
virtual bool is_animated() override;
virtual size_t loop_count() override;
virtual size_t frame_count() override;

View file

@ -150,16 +150,14 @@ ErrorOr<void> ICOImageDecoderPlugin::load_ico_bitmap(ICOLoadingContext& context,
ICOImageDescriptor& desc = context.images[real_index];
if (PNGImageDecoderPlugin::sniff({ context.data + desc.offset, desc.size })) {
auto png_decoder = TRY(PNGImageDecoderPlugin::create({ context.data + desc.offset, desc.size }));
if (png_decoder->initialize()) {
auto decoded_png_frame = TRY(png_decoder->frame(0));
if (!decoded_png_frame.image) {
dbgln_if(ICO_DEBUG, "load_ico_bitmap: failed to load PNG encoded image index: {}", real_index);
return Error::from_string_literal("Encoded image not null");
}
desc.bitmap = decoded_png_frame.image;
return {};
TRY(png_decoder->initialize());
auto decoded_png_frame = TRY(png_decoder->frame(0));
if (!decoded_png_frame.image) {
dbgln_if(ICO_DEBUG, "load_ico_bitmap: failed to load PNG encoded image index: {}", real_index);
return Error::from_string_literal("Encoded image not null");
}
return Error::from_string_literal("Couldn't initialize PNG Decoder");
desc.bitmap = decoded_png_frame.image;
return {};
} else {
auto bmp_decoder = TRY(BMPImageDecoderPlugin::create_as_included_in_ico({}, { context.data + desc.offset, desc.size }));
// NOTE: We don't initialize a BMP decoder in the usual way, but rather
@ -230,10 +228,11 @@ bool ICOImageDecoderPlugin::set_nonvolatile(bool& was_purged)
return m_context->images[0].bitmap->set_nonvolatile(was_purged);
}
bool ICOImageDecoderPlugin::initialize()
ErrorOr<void> ICOImageDecoderPlugin::initialize()
{
FixedMemoryStream stream { { m_context->data, m_context->data_size } };
return !decode_ico_header(stream).is_error();
TRY(decode_ico_header(stream));
return {};
}
bool ICOImageDecoderPlugin::is_animated()

View file

@ -22,7 +22,7 @@ public:
virtual IntSize size() override;
virtual void set_volatile() override;
[[nodiscard]] virtual bool set_nonvolatile(bool& was_purged) override;
virtual bool initialize() override;
virtual ErrorOr<void> initialize() override;
virtual bool is_animated() override;
virtual size_t loop_count() override;
virtual size_t frame_count() override;

View file

@ -47,7 +47,7 @@ static OwnPtr<ImageDecoderPlugin> probe_and_sniff_for_appropriate_plugin(Readonl
if (!sniff_result)
continue;
auto plugin_decoder = plugin.create(bytes).release_value_but_fixme_should_propagate_errors();
if (plugin_decoder->initialize())
if (!plugin_decoder->initialize().is_error())
return plugin_decoder;
}
return {};
@ -72,7 +72,7 @@ static OwnPtr<ImageDecoderPlugin> probe_and_sniff_for_appropriate_plugin_with_kn
if (!validation_result)
continue;
auto plugin_decoder = plugin.create(bytes).release_value_but_fixme_should_propagate_errors();
if (plugin_decoder->initialize())
if (!plugin_decoder->initialize().is_error())
return plugin_decoder;
}
return {};

View file

@ -34,7 +34,7 @@ public:
virtual void set_volatile() = 0;
[[nodiscard]] virtual bool set_nonvolatile(bool& was_purged) = 0;
virtual bool initialize() = 0;
virtual ErrorOr<void> initialize() = 0;
virtual bool is_animated() = 0;
virtual size_t loop_count() = 0;

View file

@ -1887,9 +1887,9 @@ bool JPEGImageDecoderPlugin::set_nonvolatile(bool& was_purged)
return m_context->bitmap->set_nonvolatile(was_purged);
}
bool JPEGImageDecoderPlugin::initialize()
ErrorOr<void> JPEGImageDecoderPlugin::initialize()
{
return true;
return {};
}
bool JPEGImageDecoderPlugin::sniff(ReadonlyBytes data)

View file

@ -25,7 +25,7 @@ public:
virtual IntSize size() override;
virtual void set_volatile() override;
[[nodiscard]] virtual bool set_nonvolatile(bool& was_purged) override;
virtual bool initialize() override;
virtual ErrorOr<void> initialize() override;
virtual bool is_animated() override;
virtual size_t loop_count() override;
virtual size_t frame_count() override;

View file

@ -1322,9 +1322,11 @@ bool PNGImageDecoderPlugin::set_nonvolatile(bool& was_purged)
return m_context->bitmap->set_nonvolatile(was_purged);
}
bool PNGImageDecoderPlugin::initialize()
ErrorOr<void> PNGImageDecoderPlugin::initialize()
{
return decode_png_header(*m_context);
if (decode_png_header(*m_context))
return {};
return Error::from_string_literal("bad image header");
}
bool PNGImageDecoderPlugin::sniff(ReadonlyBytes data)

View file

@ -22,7 +22,7 @@ public:
virtual IntSize size() override;
virtual void set_volatile() override;
[[nodiscard]] virtual bool set_nonvolatile(bool& was_purged) override;
virtual bool initialize() override;
virtual ErrorOr<void> initialize() override;
virtual bool is_animated() override;
virtual size_t loop_count() override;
virtual size_t frame_count() override;

View file

@ -67,7 +67,7 @@ public:
virtual void set_volatile() override;
[[nodiscard]] virtual bool set_nonvolatile(bool& was_purged) override;
virtual bool initialize() override { return true; }
virtual ErrorOr<void> initialize() override { return {}; }
virtual bool is_animated() override;
virtual size_t loop_count() override;
virtual size_t frame_count() override;

View file

@ -195,9 +195,9 @@ bool QOIImageDecoderPlugin::set_nonvolatile(bool& was_purged)
return m_context->bitmap->set_nonvolatile(was_purged);
}
bool QOIImageDecoderPlugin::initialize()
ErrorOr<void> QOIImageDecoderPlugin::initialize()
{
return !decode_header_and_update_context(*m_context->stream).is_error();
return decode_header_and_update_context(*m_context->stream);
}
bool QOIImageDecoderPlugin::sniff(ReadonlyBytes data)

View file

@ -46,7 +46,7 @@ public:
virtual IntSize size() override;
virtual void set_volatile() override;
[[nodiscard]] virtual bool set_nonvolatile(bool& was_purged) override;
virtual bool initialize() override;
virtual ErrorOr<void> initialize() override;
virtual bool is_animated() override { return false; }
virtual size_t loop_count() override { return 0; }
virtual size_t frame_count() override { return 1; }

View file

@ -219,9 +219,11 @@ bool TGAImageDecoderPlugin::decode_tga_header()
return true;
}
bool TGAImageDecoderPlugin::initialize()
ErrorOr<void> TGAImageDecoderPlugin::initialize()
{
return decode_tga_header();
if (decode_tga_header())
return {};
return Error::from_string_literal("Bad TGA header");
}
ErrorOr<bool> TGAImageDecoderPlugin::validate_before_create(ReadonlyBytes data)

View file

@ -23,7 +23,7 @@ public:
virtual IntSize size() override;
virtual void set_volatile() override;
[[nodiscard]] virtual bool set_nonvolatile(bool& was_purged) override;
virtual bool initialize() override;
virtual ErrorOr<void> initialize() override;
virtual bool is_animated() override;
virtual size_t loop_count() override;
virtual size_t frame_count() override;

View file

@ -629,7 +629,7 @@ WebPImageDecoderPlugin::WebPImageDecoderPlugin(ReadonlyBytes data, OwnPtr<WebPLo
WebPImageDecoderPlugin::~WebPImageDecoderPlugin() = default;
bool WebPImageDecoderPlugin::set_error(ErrorOr<void>&& error_or)
bool WebPImageDecoderPlugin::set_error(ErrorOr<void> const& error_or)
{
if (error_or.is_error()) {
m_context->state = WebPLoadingContext::State::Error;
@ -664,9 +664,11 @@ bool WebPImageDecoderPlugin::set_nonvolatile(bool& was_purged)
return m_context->bitmap->set_nonvolatile(was_purged);
}
bool WebPImageDecoderPlugin::initialize()
ErrorOr<void> WebPImageDecoderPlugin::initialize()
{
return !set_error(decode_webp_header(*m_context));
auto header_okay_or_error = decode_webp_header(*m_context);
set_error(header_okay_or_error);
return header_okay_or_error;
}
bool WebPImageDecoderPlugin::sniff(ReadonlyBytes data)

View file

@ -22,7 +22,7 @@ public:
virtual IntSize size() override;
virtual void set_volatile() override;
[[nodiscard]] virtual bool set_nonvolatile(bool& was_purged) override;
virtual bool initialize() override;
virtual ErrorOr<void> initialize() override;
virtual bool is_animated() override;
virtual size_t loop_count() override;
virtual size_t frame_count() override;
@ -31,7 +31,7 @@ public:
virtual ErrorOr<Optional<ReadonlyBytes>> icc_data() override;
private:
bool set_error(ErrorOr<void>&&);
bool set_error(ErrorOr<void> const&);
WebPImageDecoderPlugin(ReadonlyBytes, OwnPtr<WebPLoadingContext>);

View file

@ -272,10 +272,9 @@ PDFErrorOr<ByteBuffer> Filter::decode_dct(ReadonlyBytes bytes)
{
if (Gfx::JPEGImageDecoderPlugin::sniff({ bytes.data(), bytes.size() })) {
auto decoder = Gfx::JPEGImageDecoderPlugin::create({ bytes.data(), bytes.size() }).release_value_but_fixme_should_propagate_errors();
if (decoder->initialize()) {
auto frame = TRY(decoder->frame(0));
return TRY(frame.image->serialize_to_byte_buffer());
}
TRY(decoder->initialize());
auto frame = TRY(decoder->frame(0));
return TRY(frame.image->serialize_to_byte_buffer());
}
return AK::Error::from_string_literal("Not a JPEG image!");
};

View file

@ -143,19 +143,19 @@ void SpiceAgent::on_message_received()
if (type == ClipboardType::PNG) {
if (Gfx::PNGImageDecoderPlugin::sniff({ data_buffer.data(), data_buffer.size() })) {
auto png_decoder = Gfx::PNGImageDecoderPlugin::create({ data_buffer.data(), data_buffer.size() }).release_value_but_fixme_should_propagate_errors();
if (png_decoder->initialize())
if (!png_decoder->initialize().is_error())
frame_or_error = png_decoder->frame(0);
}
} else if (type == ClipboardType::BMP) {
if (Gfx::BMPImageDecoderPlugin::sniff({ data_buffer.data(), data_buffer.size() })) {
auto bmp_decoder = Gfx::BMPImageDecoderPlugin::create({ data_buffer.data(), data_buffer.size() }).release_value_but_fixme_should_propagate_errors();
if (bmp_decoder->initialize())
if (!bmp_decoder->initialize().is_error())
frame_or_error = bmp_decoder->frame(0);
}
} else if (type == ClipboardType::JPEG) {
if (Gfx::JPEGImageDecoderPlugin::sniff({ data_buffer.data(), data_buffer.size() })) {
auto jpeg_decoder = Gfx::JPEGImageDecoderPlugin::create({ data_buffer.data(), data_buffer.size() }).release_value_but_fixme_should_propagate_errors();
if (jpeg_decoder->initialize())
if (!jpeg_decoder->initialize().is_error())
frame_or_error = jpeg_decoder->frame(0);
}
} else {