mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 23:50:19 +00:00
LibGfx: Make all image decoders reject image sizes above 16384 pixels
Let's just say no to shenanigans by capping images at 16384 pixels both wide and tall. If a day comes in the future where we need to handle images larger than this, we can deal with it then.
This commit is contained in:
parent
a5f4cb78cf
commit
edf01803cd
Notes:
sideshowbarker
2024-07-19 00:37:24 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/edf01803cd3
7 changed files with 38 additions and 10 deletions
|
@ -518,6 +518,11 @@ static bool decode_bmp_core_dib(BMPLoadingContext& context, Streamer& streamer)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (static_cast<size_t>(core.width) > maximum_width_for_decoded_images || static_cast<size_t>(abs(core.height)) > maximum_height_for_decoded_images) {
|
||||||
|
dbgln("This BMP is too large for comfort: {}x{}", core.width, abs(core.height));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
auto color_planes = streamer.read_u16();
|
auto color_planes = streamer.read_u16();
|
||||||
if (color_planes != 1) {
|
if (color_planes != 1) {
|
||||||
IF_BMP_DEBUG(dbg() << "BMP has an invalid number of color planes: " << color_planes);
|
IF_BMP_DEBUG(dbg() << "BMP has an invalid number of color planes: " << color_planes);
|
||||||
|
|
|
@ -424,6 +424,11 @@ static bool load_gif_frame_descriptors(GIFLoadingContext& context)
|
||||||
if (stream.handle_any_error())
|
if (stream.handle_any_error())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (context.logical_screen.width > maximum_width_for_decoded_images || context.logical_screen.height > maximum_height_for_decoded_images) {
|
||||||
|
dbgln("This GIF is too large for comfort: {}x{}", context.logical_screen.width, context.logical_screen.height);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
u8 gcm_info = 0;
|
u8 gcm_info = 0;
|
||||||
stream >> gcm_info;
|
stream >> gcm_info;
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,9 @@ namespace Gfx {
|
||||||
|
|
||||||
class Bitmap;
|
class Bitmap;
|
||||||
|
|
||||||
|
static constexpr size_t maximum_width_for_decoded_images = 16384;
|
||||||
|
static constexpr size_t maximum_height_for_decoded_images = 16384;
|
||||||
|
|
||||||
struct ImageFrameDescriptor {
|
struct ImageFrameDescriptor {
|
||||||
RefPtr<Bitmap> image;
|
RefPtr<Bitmap> image;
|
||||||
int duration { 0 };
|
int duration { 0 };
|
||||||
|
|
|
@ -776,6 +776,12 @@ static bool read_start_of_frame(InputMemoryStream& stream, JPGLoadingContext& co
|
||||||
#endif
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (context.frame.width > maximum_width_for_decoded_images || context.frame.height > maximum_height_for_decoded_images) {
|
||||||
|
dbgln("This JPEG is too large for comfort: {}x{}", context.frame.width, context.frame.height);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
set_macroblock_metadata(context);
|
set_macroblock_metadata(context);
|
||||||
|
|
||||||
stream >> context.component_count;
|
stream >> context.component_count;
|
||||||
|
|
|
@ -60,8 +60,8 @@ struct PBMLoadingContext {
|
||||||
State state { State::NotDecoded };
|
State state { State::NotDecoded };
|
||||||
const u8* data { nullptr };
|
const u8* data { nullptr };
|
||||||
size_t data_size { 0 };
|
size_t data_size { 0 };
|
||||||
int width { -1 };
|
size_t width { 0 };
|
||||||
int height { -1 };
|
size_t height { 0 };
|
||||||
RefPtr<Gfx::Bitmap> bitmap;
|
RefPtr<Gfx::Bitmap> bitmap;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -853,8 +853,8 @@ static bool process_IHDR(ReadonlyBytes data, PNGLoadingContext& context)
|
||||||
return false;
|
return false;
|
||||||
auto& ihdr = *(const PNG_IHDR*)data.data();
|
auto& ihdr = *(const PNG_IHDR*)data.data();
|
||||||
|
|
||||||
if (ihdr.width > NumericLimits<i32>::max() || ihdr.height > NumericLimits<i32>::max()) {
|
if (ihdr.width > maximum_width_for_decoded_images || ihdr.height > maximum_height_for_decoded_images) {
|
||||||
dbgln("PNG has invalid geometry {}x{}", (u32)ihdr.width, (u32)ihdr.height);
|
dbgln("This PNG is too large for comfort: {}x{}", (u32)ihdr.width, (u32)ihdr.height);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2020, the SerenityOS developers, Hüseyin ASLITÜRK <asliturk@hotmail.com>
|
* Copyright (c) 2020, Hüseyin Aslıtürk <asliturk@hotmail.com>
|
||||||
|
* Copyright (c) 2020, the SerenityOS developers
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -26,7 +27,6 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Streamer.h"
|
|
||||||
#include <AK/Array.h>
|
#include <AK/Array.h>
|
||||||
#include <AK/Endian.h>
|
#include <AK/Endian.h>
|
||||||
#include <AK/LexicalPath.h>
|
#include <AK/LexicalPath.h>
|
||||||
|
@ -36,6 +36,10 @@
|
||||||
#include <AK/StringBuilder.h>
|
#include <AK/StringBuilder.h>
|
||||||
#include <AK/Types.h>
|
#include <AK/Types.h>
|
||||||
#include <AK/Vector.h>
|
#include <AK/Vector.h>
|
||||||
|
#include <LibGfx/Bitmap.h>
|
||||||
|
#include <LibGfx/Color.h>
|
||||||
|
#include <LibGfx/ImageDecoder.h>
|
||||||
|
#include <LibGfx/Streamer.h>
|
||||||
|
|
||||||
//#define PORTABLE_IMAGE_LOADER_DEBUG
|
//#define PORTABLE_IMAGE_LOADER_DEBUG
|
||||||
|
|
||||||
|
@ -216,8 +220,8 @@ template<typename TContext>
|
||||||
static void set_adjusted_pixels(TContext& context, const AK::Vector<Gfx::Color>& color_data)
|
static void set_adjusted_pixels(TContext& context, const AK::Vector<Gfx::Color>& color_data)
|
||||||
{
|
{
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
for (int y = 0; y < context.height; ++y) {
|
for (size_t y = 0; y < context.height; ++y) {
|
||||||
for (int x = 0; x < context.width; ++x) {
|
for (size_t x = 0; x < context.width; ++x) {
|
||||||
Color color = color_data.at(index);
|
Color color = color_data.at(index);
|
||||||
if (context.max_val < 255) {
|
if (context.max_val < 255) {
|
||||||
color = adjust_color(context.max_val, color);
|
color = adjust_color(context.max_val, color);
|
||||||
|
@ -232,8 +236,8 @@ template<typename TContext>
|
||||||
static void set_pixels(TContext& context, const AK::Vector<Gfx::Color>& color_data)
|
static void set_pixels(TContext& context, const AK::Vector<Gfx::Color>& color_data)
|
||||||
{
|
{
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
for (int y = 0; y < context.height; ++y) {
|
for (size_t y = 0; y < context.height; ++y) {
|
||||||
for (int x = 0; x < context.width; ++x) {
|
for (size_t x = 0; x < context.width; ++x) {
|
||||||
context.bitmap->set_pixel(x, y, color_data.at(index));
|
context.bitmap->set_pixel(x, y, color_data.at(index));
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
@ -267,6 +271,11 @@ static bool decode(TContext& context)
|
||||||
if (!read_height(context, streamer))
|
if (!read_height(context, streamer))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (context.width > maximum_width_for_decoded_images || context.height > maximum_height_for_decoded_images) {
|
||||||
|
dbgln("This portable network image is too large for comfort: {}x{}", context.width, context.height);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!read_white_space(context, streamer))
|
if (!read_white_space(context, streamer))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue