diff --git a/src/modules/_Image_TIFF/configure.in b/src/modules/_Image_TIFF/configure.in index ca889a2ed41b6ea0c2fed8b4827d59e8c9380f72..d60bcc1eeb76eefa15532280b1f7b5dafc80d360 100644 --- a/src/modules/_Image_TIFF/configure.in +++ b/src/modules/_Image_TIFF/configure.in @@ -15,6 +15,7 @@ if test x$with_tifflib = xyes ; then AC_CHECK_LIB(jpeg, jpeg_CreateCompress) AC_SEARCH_LIBS(inflate, z gz zlib) AC_SEARCH_LIBS(TIFFOpen, tiff libtiff) + AC_CHECK_SIZEOF(tsize_t, 4, [#include <tiffio.h>]) AC_MSG_CHECKING([if this tifflib is working]) AC_CACHE_VAL(pike_cv_working_tiff, [ diff --git a/src/modules/_Image_TIFF/image_tiff.c b/src/modules/_Image_TIFF/image_tiff.c index c13b875426756567f61f84ee583003e79d39fde3..a7fa7e05e5cb98d02a076ec5e91b815cf73a8a41 100644 --- a/src/modules/_Image_TIFF/image_tiff.c +++ b/src/modules/_Image_TIFF/image_tiff.c @@ -31,6 +31,7 @@ #include "pike_error.h" #include "stralloc.h" #include "operators.h" +#include "bignum.h" #include "../Image/image.h" #ifdef INLINE @@ -430,7 +431,8 @@ void low_image_tiff_decode( struct buffer *buf, { TIFF *tif; unsigned int i; - uint32 w, h, *raster, *s; + uint32 w, h, pixels, *raster, *s; + tsize_t bytes_needed; rgb_group *di, *da=NULL; tif = TIFFClientOpen("memoryfile", "r", (thandle_t) buf, read_buffer, write_buffer, @@ -442,11 +444,37 @@ void low_image_tiff_decode( struct buffer *buf, TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w); TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h); - s = raster = (uint32 *)_TIFFmalloc(w*h*sizeof(uint32)); + + if (DO_UINT32_MUL_OVERFLOW(w, h, &pixels) + || pixels > 0x7fffffff) { + /* There is no need to continue, Image.Image does not support >2G + * pixels. */ + TIFFClose(tif); + Pike_error("Image.TIFF: Image too large (%u x %u >2G pixels)\n", + w, h); + } + +#if SIZEOF_TSIZE_T == 8 + /* We can expect sizeof(uint32) * pixels to fit into a tsize_t. */ + bytes_needed = (tsize_t)pixels * sizeof(uint32); +#else /* reasonably safe to assume sizeof(tsize_t) == 4 */ + /* tsize_t is signed, the amount of space we need may not fit into the + * type. */ + if (!(DO_UINT32_MUL_OVERFLOW(pixels, sizeof(uint32), &pixels) + || pixels > MAX_INT)) { + bytes_needed = pixels; + } else { + TIFFClose(tif); + Pike_error("Image.TIFF: Cannot allocate buffer for %u x %u image.\n", + w, h); + } +#endif + + s = raster = (uint32 *)_TIFFmalloc(bytes_needed); if (raster == NULL) { TIFFClose (tif); - Pike_error("Malloc failed to allocate buffer for %ldx%ld image\n", - (long)w, (long)h); + Pike_error("Malloc failed to allocate buffer for %ux%u image\n", + w, h); } if(!TIFFReadRGBAImage(tif, w, h, raster, 0)) {