Limit dimensions of all image loaders to 23000x23000

This commit is contained in:
sfan5 2021-09-30 16:40:41 +02:00
parent 594de99153
commit dbd39120e7
5 changed files with 24 additions and 2 deletions

@ -13,6 +13,13 @@ namespace irr
namespace video namespace video
{ {
//! check sanity of image dimensions to prevent issues later, for use by CImageLoaders
inline bool checkImageDimensions(u32 width, u32 height)
{
// 4 * 23000 * 23000 is just under S32_MAX
return width <= 23000 && height <= 23000;
}
//! IImage implementation with a lot of special image operations for //! IImage implementation with a lot of special image operations for
//! 16 bit A1R5G5B5/32 Bit A8R8G8B8 images, which are used by the SoftwareDevice. //! 16 bit A1R5G5B5/32 Bit A8R8G8B8 images, which are used by the SoftwareDevice.
class CImage : public IImage class CImage : public IImage

@ -252,6 +252,12 @@ IImage* CImageLoaderBMP::loadImage(io::IReadFile* file) const
return 0; return 0;
} }
if (header.BPP > 32 || !checkImageDimensions(header.Width, header.Height))
{
os::Printer::log("Rejecting BMP with unreasonable size or BPP.", ELL_ERROR);
return 0;
}
// adjust bitmap data size to dword boundary // adjust bitmap data size to dword boundary
header.BitmapDataSize += (4-(header.BitmapDataSize%4))%4; header.BitmapDataSize += (4-(header.BitmapDataSize%4))%4;

@ -221,8 +221,8 @@ IImage* CImageLoaderJPG::loadImage(io::IReadFile* file) const
cinfo.output_gamma=2.2; cinfo.output_gamma=2.2;
cinfo.do_fancy_upsampling=FALSE; cinfo.do_fancy_upsampling=FALSE;
// reject unreasonable sizes (4 * 32000 * 32000 is just under U32_MAX) // reject unreasonable sizes
if (cinfo.image_width > 32000 || cinfo.image_height > 32000) if (!checkImageDimensions(cinfo.image_width, cinfo.image_height))
longjmp(jerr.setjmp_buffer, 1); longjmp(jerr.setjmp_buffer, 1);
// Start decompressor // Start decompressor

@ -154,6 +154,9 @@ IImage* CImageLoaderPng::loadImage(io::IReadFile* file) const
Height=h; Height=h;
} }
if (!checkImageDimensions(Width, Height))
png_cpexcept_error(png_ptr, "Unreasonable size");
// Convert palette color to true color // Convert palette color to true color
if (ColorType==PNG_COLOR_TYPE_PALETTE) if (ColorType==PNG_COLOR_TYPE_PALETTE)
png_set_palette_to_rgb(png_ptr); png_set_palette_to_rgb(png_ptr);

@ -106,6 +106,12 @@ IImage* CImageLoaderTGA::loadImage(io::IReadFile* file) const
header.ImageHeight = os::Byteswap::byteswap(header.ImageHeight); header.ImageHeight = os::Byteswap::byteswap(header.ImageHeight);
#endif #endif
if (!checkImageDimensions(header.ImageWidth, header.ImageHeight))
{
os::Printer::log("Rejecting TGA with unreasonable size.", ELL_ERROR);
return 0;
}
// skip image identification field // skip image identification field
if (header.IdLength) if (header.IdLength)
file->seek(header.IdLength, true); file->seek(header.IdLength, true);