From dbd39120e7ed8c0c97e48e2df62347627f3c1d42 Mon Sep 17 00:00:00 2001 From: sfan5 Date: Thu, 30 Sep 2021 16:40:41 +0200 Subject: [PATCH] Limit dimensions of all image loaders to 23000x23000 --- source/Irrlicht/CImage.h | 7 +++++++ source/Irrlicht/CImageLoaderBMP.cpp | 6 ++++++ source/Irrlicht/CImageLoaderJPG.cpp | 4 ++-- source/Irrlicht/CImageLoaderPNG.cpp | 3 +++ source/Irrlicht/CImageLoaderTGA.cpp | 6 ++++++ 5 files changed, 24 insertions(+), 2 deletions(-) diff --git a/source/Irrlicht/CImage.h b/source/Irrlicht/CImage.h index 0662ff5f..48d45b3b 100644 --- a/source/Irrlicht/CImage.h +++ b/source/Irrlicht/CImage.h @@ -13,6 +13,13 @@ namespace irr 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 //! 16 bit A1R5G5B5/32 Bit A8R8G8B8 images, which are used by the SoftwareDevice. class CImage : public IImage diff --git a/source/Irrlicht/CImageLoaderBMP.cpp b/source/Irrlicht/CImageLoaderBMP.cpp index 675212b1..234c5157 100644 --- a/source/Irrlicht/CImageLoaderBMP.cpp +++ b/source/Irrlicht/CImageLoaderBMP.cpp @@ -252,6 +252,12 @@ IImage* CImageLoaderBMP::loadImage(io::IReadFile* file) const 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 header.BitmapDataSize += (4-(header.BitmapDataSize%4))%4; diff --git a/source/Irrlicht/CImageLoaderJPG.cpp b/source/Irrlicht/CImageLoaderJPG.cpp index 56acae4f..0d19d713 100644 --- a/source/Irrlicht/CImageLoaderJPG.cpp +++ b/source/Irrlicht/CImageLoaderJPG.cpp @@ -221,8 +221,8 @@ IImage* CImageLoaderJPG::loadImage(io::IReadFile* file) const cinfo.output_gamma=2.2; cinfo.do_fancy_upsampling=FALSE; - // reject unreasonable sizes (4 * 32000 * 32000 is just under U32_MAX) - if (cinfo.image_width > 32000 || cinfo.image_height > 32000) + // reject unreasonable sizes + if (!checkImageDimensions(cinfo.image_width, cinfo.image_height)) longjmp(jerr.setjmp_buffer, 1); // Start decompressor diff --git a/source/Irrlicht/CImageLoaderPNG.cpp b/source/Irrlicht/CImageLoaderPNG.cpp index 8b988943..9638421d 100644 --- a/source/Irrlicht/CImageLoaderPNG.cpp +++ b/source/Irrlicht/CImageLoaderPNG.cpp @@ -154,6 +154,9 @@ IImage* CImageLoaderPng::loadImage(io::IReadFile* file) const Height=h; } + if (!checkImageDimensions(Width, Height)) + png_cpexcept_error(png_ptr, "Unreasonable size"); + // Convert palette color to true color if (ColorType==PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png_ptr); diff --git a/source/Irrlicht/CImageLoaderTGA.cpp b/source/Irrlicht/CImageLoaderTGA.cpp index c9b3a9d5..af4fad55 100644 --- a/source/Irrlicht/CImageLoaderTGA.cpp +++ b/source/Irrlicht/CImageLoaderTGA.cpp @@ -106,6 +106,12 @@ IImage* CImageLoaderTGA::loadImage(io::IReadFile* file) const header.ImageHeight = os::Byteswap::byteswap(header.ImageHeight); #endif + if (!checkImageDimensions(header.ImageWidth, header.ImageHeight)) + { + os::Printer::log("Rejecting TGA with unreasonable size.", ELL_ERROR); + return 0; + } + // skip image identification field if (header.IdLength) file->seek(header.IdLength, true);