From c7d0c2ee7aa8132eea998eaf935b1fbee6037455 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sun, 20 Dec 2020 16:04:29 +0100 Subject: [PATCH] LibGfx: Teach all image decoders to fail on bitmap allocation failure We don't need to wait for oss-fuzz to find this for us. :^) --- Libraries/LibGfx/GIFLoader.cpp | 4 ++++ Libraries/LibGfx/ICOLoader.cpp | 2 ++ Libraries/LibGfx/JPGLoader.cpp | 9 +++++++-- Libraries/LibGfx/PBMLoader.cpp | 4 ++++ Libraries/LibGfx/PGMLoader.cpp | 4 ++++ Libraries/LibGfx/PNGLoader.cpp | 2 ++ Libraries/LibGfx/PPMLoader.cpp | 4 ++++ 7 files changed, 27 insertions(+), 2 deletions(-) diff --git a/Libraries/LibGfx/GIFLoader.cpp b/Libraries/LibGfx/GIFLoader.cpp index 0fc1c42ff8..1b36361cc8 100644 --- a/Libraries/LibGfx/GIFLoader.cpp +++ b/Libraries/LibGfx/GIFLoader.cpp @@ -297,7 +297,11 @@ static bool decode_frame(GIFLoadingContext& context, size_t frame_index) if (context.state < GIFLoadingContext::State::FrameComplete) { start_frame = 0; context.frame_buffer = Bitmap::create_purgeable(BitmapFormat::RGBA32, { context.logical_screen.width, context.logical_screen.height }); + if (!context.frame_buffer) + return false; context.prev_frame_buffer = Bitmap::create_purgeable(BitmapFormat::RGBA32, { context.logical_screen.width, context.logical_screen.height }); + if (!context.prev_frame_buffer) + return false; } else if (frame_index < context.current_frame) { start_frame = 0; } diff --git a/Libraries/LibGfx/ICOLoader.cpp b/Libraries/LibGfx/ICOLoader.cpp index d2c2716ef9..72fb62663b 100644 --- a/Libraries/LibGfx/ICOLoader.cpp +++ b/Libraries/LibGfx/ICOLoader.cpp @@ -292,6 +292,8 @@ static bool load_ico_bmp(ICOLoadingContext& context, ImageDescriptor& desc) } desc.bitmap = Bitmap::create_purgeable(BitmapFormat::RGBA32, { desc.width, desc.height }); + if (!desc.bitmap) + return false; Bitmap& bitmap = *desc.bitmap; const u8* image_base = context.data + desc.offset + sizeof(info); const BMP_ARGB* data_base = (const BMP_ARGB*)image_base; diff --git a/Libraries/LibGfx/JPGLoader.cpp b/Libraries/LibGfx/JPGLoader.cpp index fe9e8c33db..dd97c80074 100644 --- a/Libraries/LibGfx/JPGLoader.cpp +++ b/Libraries/LibGfx/JPGLoader.cpp @@ -1126,9 +1126,11 @@ static void ycbcr_to_rgb(const JPGLoadingContext& context, Vector& m } } -static void compose_bitmap(JPGLoadingContext& context, const Vector& macroblocks) +static bool compose_bitmap(JPGLoadingContext& context, const Vector& macroblocks) { context.bitmap = Bitmap::create_purgeable(BitmapFormat::RGB32, { context.frame.width, context.frame.height }); + if (!context.bitmap) + return false; for (u32 y = context.frame.height - 1; y < context.frame.height; y--) { const u32 block_row = y / 8; @@ -1142,6 +1144,8 @@ static void compose_bitmap(JPGLoadingContext& context, const Vector& context.bitmap->set_pixel(x, y, color); } } + + return true; } static bool parse_header(InputMemoryStream& stream, JPGLoadingContext& context) @@ -1288,7 +1292,8 @@ static bool decode_jpg(JPGLoadingContext& context) dequantize(context, macroblocks); inverse_dct(context, macroblocks); ycbcr_to_rgb(context, macroblocks); - compose_bitmap(context, macroblocks); + if (!compose_bitmap(context, macroblocks)) + return false; return true; } diff --git a/Libraries/LibGfx/PBMLoader.cpp b/Libraries/LibGfx/PBMLoader.cpp index c4001375cc..9aeba49c07 100644 --- a/Libraries/LibGfx/PBMLoader.cpp +++ b/Libraries/LibGfx/PBMLoader.cpp @@ -266,6 +266,10 @@ static bool read_image_data(PBMLoadingContext& context, Streamer& streamer) } context.bitmap = Bitmap::create_purgeable(BitmapFormat::RGB32, { context.width, context.height }); + if (!context.bitmap) { + context.state = PBMLoadingContext::State::Error; + return false; + } size_t index = 0; for (int y = 0; y < context.height; ++y) { diff --git a/Libraries/LibGfx/PGMLoader.cpp b/Libraries/LibGfx/PGMLoader.cpp index 40c3ff2272..646a17aef5 100644 --- a/Libraries/LibGfx/PGMLoader.cpp +++ b/Libraries/LibGfx/PGMLoader.cpp @@ -287,6 +287,10 @@ static bool read_image_data(PGMLoadingContext& context, Streamer& streamer) } context.bitmap = Bitmap::create_purgeable(BitmapFormat::RGB32, { context.width, context.height }); + if (!context.bitmap) { + context.state = PGMLoadingContext::State::Error; + return false; + } size_t index = 0; for (int y = 0; y < context.height; ++y) { diff --git a/Libraries/LibGfx/PNGLoader.cpp b/Libraries/LibGfx/PNGLoader.cpp index 47b03ff391..02a3391ebe 100644 --- a/Libraries/LibGfx/PNGLoader.cpp +++ b/Libraries/LibGfx/PNGLoader.cpp @@ -734,6 +734,8 @@ static bool decode_png_adam7(PNGLoadingContext& context) { Streamer streamer(context.decompression_buffer, context.decompression_buffer_size); context.bitmap = Bitmap::create_purgeable(context.has_alpha() ? BitmapFormat::RGBA32 : BitmapFormat::RGB32, { context.width, context.height }); + if (!context.bitmap) + return false; for (int pass = 1; pass <= 7; ++pass) { if (!decode_adam7_pass(context, streamer, pass)) diff --git a/Libraries/LibGfx/PPMLoader.cpp b/Libraries/LibGfx/PPMLoader.cpp index e41a2cfb57..3ada07f73c 100644 --- a/Libraries/LibGfx/PPMLoader.cpp +++ b/Libraries/LibGfx/PPMLoader.cpp @@ -319,6 +319,10 @@ static bool read_image_data(PPMLoadingContext& context, Streamer& streamer) return false; context.bitmap = Bitmap::create_purgeable(BitmapFormat::RGB32, { context.width, context.height }); + if (!context.bitmap) { + context.state = PPMLoadingContext::State::Error; + return false; + } size_t index = 0; for (int y = 0; y < context.height; ++y) {