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);