From 76d013d9d6dd405f9dcca1e3a41818335dc40e51 Mon Sep 17 00:00:00 2001 From: cutealien Date: Fri, 6 May 2022 16:00:26 +0000 Subject: [PATCH] Fix crash with large jpg files. Based somewhat on a patch in Minetest from sfan5 https://github.com/minetest/irrlicht/commit/594de9915346a87f67cd94e28c7933993efb5d3b There might be more problems which may be the reason they checked for other values in Minetest, but don't have more info for now and so far this works. Forum: https://irrlicht.sourceforge.io/forum/viewtopic.php?f=2&t=52819&p=306518 git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@6385 dfc29bdd-3216-0410-991c-e03cc46cb475 --- changes.txt | 1 + source/Irrlicht/CImageLoaderJPG.cpp | 21 ++++++++++++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/changes.txt b/changes.txt index f5e8011..d2d0bca 100644 --- a/changes.txt +++ b/changes.txt @@ -1,6 +1,7 @@ -------------------------- Changes in 1.9 (not yet released) +- Fix crash with large jpg files. Based somewhat on a patch in Minetest from sfan5 https://github.com/minetest/irrlicht/commit/594de9915346a87f67cd94e28c7933993efb5d3b - COSOperator::getSystemMemory now returns some value on OSX (thought same for total and available). Thanks @sfan5 for patch https://irrlicht.sourceforge.io/forum/viewtopic.php?f=2&t=52819 and https://github.com/minetest/irrlicht/commit/e469c54f76f6d24f92389b4e8a27b9cce7152888 - Fix CVertexBuffer::setType switching types for non-empty arrays. Before we had some bad casts which could result in random initializing of some vertex data. diff --git a/source/Irrlicht/CImageLoaderJPG.cpp b/source/Irrlicht/CImageLoaderJPG.cpp index 72ba484..af807ab 100644 --- a/source/Irrlicht/CImageLoaderJPG.cpp +++ b/source/Irrlicht/CImageLoaderJPG.cpp @@ -145,10 +145,13 @@ IImage* CImageLoaderJPG::loadImage(io::IReadFile* file) const return 0; core::stringc filename = file->getFileName(); + long fileSize = file->getSize(); + if ( fileSize < 3 ) + return 0; u8 **rowPtr=0; - u8* input = new u8[file->getSize()]; - file->read(input, file->getSize()); + u8* input = new u8[fileSize]; + file->read(input, fileSize); // allocate and initialize JPEG decompression object struct jpeg_decompress_struct cinfo; @@ -188,7 +191,7 @@ IImage* CImageLoaderJPG::loadImage(io::IReadFile* file) const jpeg_source_mgr jsrc; // Set up data pointer - jsrc.bytes_in_buffer = file->getSize(); + jsrc.bytes_in_buffer = fileSize; jsrc.next_input_byte = (JOCTET*)input; cinfo.src = &jsrc; @@ -225,10 +228,17 @@ IImage* CImageLoaderJPG::loadImage(io::IReadFile* file) const jpeg_start_decompress(&cinfo); // Get image data - u16 rowspan = cinfo.image_width * cinfo.out_color_components; + u32 rowspan = cinfo.image_width * cinfo.out_color_components; u32 width = cinfo.image_width; u32 height = cinfo.image_height; + if ( width > JPEG_MAX_DIMENSION || height > JPEG_MAX_DIMENSION ) + { + os::Printer::log("Image dimensions too large for JPG in file", filename, ELL_WARNING); + longjmp(jerr.setjmp_buffer, 1); + } + + // Allocate memory for buffer u8* output = new u8[rowspan * height]; @@ -237,7 +247,7 @@ IImage* CImageLoaderJPG::loadImage(io::IReadFile* file) const // Create array of row pointers for lib rowPtr = new u8* [height]; - for( u32 i = 0; i < height; i++ ) + for( size_t i = 0; i < height; i++ ) rowPtr[i] = &output[ i * rowspan ]; u32 rowsRead = 0; @@ -246,6 +256,7 @@ IImage* CImageLoaderJPG::loadImage(io::IReadFile* file) const rowsRead += jpeg_read_scanlines( &cinfo, &rowPtr[rowsRead], cinfo.output_height - rowsRead ); delete [] rowPtr; + rowPtr = 0; // Finish decompression jpeg_finish_decompress(&cinfo);