1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-06-27 16:36:03 +00:00

ImageSource: restrict max dimensions to protect from integer overflows (#15965)

This commit is contained in:
sfan5 2025-04-01 19:12:37 +02:00 committed by GitHub
parent 0179021acc
commit 47c75b3294
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 19 additions and 8 deletions

View file

@ -949,9 +949,10 @@ static void imageTransform(u32 transform, video::IImage *src, video::IImage *dst
#define CHECK_DIM(w, h) \ #define CHECK_DIM(w, h) \
do { \ do { \
if ((w) <= 0 || (h) <= 0 || (w) >= 0xffff || (h) >= 0xffff) { \ if ((w) <= 0 || (w) > MAX_IMAGE_DIMENSION) \
COMPLAIN_INVALID("width or height"); \ COMPLAIN_INVALID("width"); \
} \ if ((h) <= 0 || (h) > MAX_IMAGE_DIMENSION) \
COMPLAIN_INVALID("height"); \
} while(0) } while(0)
bool ImageSource::generateImagePart(std::string_view part_of_name, bool ImageSource::generateImagePart(std::string_view part_of_name,
@ -1350,6 +1351,8 @@ bool ImageSource::generateImagePart(std::string_view part_of_name,
v2u32 frame_size = baseimg->getDimension(); v2u32 frame_size = baseimg->getDimension();
frame_size.Y /= frame_count; frame_size.Y /= frame_count;
if (frame_size.Y == 0)
frame_size.Y = 1;
video::IImage *img = driver->createImage(video::ECF_A8R8G8B8, video::IImage *img = driver->createImage(video::ECF_A8R8G8B8,
frame_size); frame_size);
@ -1498,11 +1501,13 @@ bool ImageSource::generateImagePart(std::string_view part_of_name,
u32 w = scale * dim.Width; u32 w = scale * dim.Width;
u32 h = scale * dim.Height; u32 h = scale * dim.Height;
const core::dimension2d<u32> newdim(w, h); const core::dimension2d<u32> newdim(w, h);
video::IImage *newimg = driver->createImage( if (w <= MAX_IMAGE_DIMENSION && h <= MAX_IMAGE_DIMENSION) {
baseimg->getColorFormat(), newdim); video::IImage *newimg = driver->createImage(
baseimg->copyToScaling(newimg); baseimg->getColorFormat(), newdim);
baseimg->drop(); baseimg->copyToScaling(newimg);
baseimg = newimg; baseimg->drop();
baseimg = newimg;
}
} }
} }
} }

View file

@ -45,6 +45,12 @@ struct ImageSource {
// Insert a source image into the cache without touching the filesystem. // Insert a source image into the cache without touching the filesystem.
void insertSourceImage(const std::string &name, video::IImage *img, bool prefer_local); void insertSourceImage(const std::string &name, video::IImage *img, bool prefer_local);
// This was picked so that the image buffer size fits in an s32 (assuming 32bpp).
// The exact value is 23170 but this provides some leeway.
// In theory something like 33333x123 could be allowed, but there is no strong
// need or argument. Irrlicht also has the same limit.
static constexpr int MAX_IMAGE_DIMENSION = 23000;
private: private:
// Generate image based on a string like "stone.png" or "[crack:1:0". // Generate image based on a string like "stone.png" or "[crack:1:0".