diff --git a/src/modules/_Image_TIFF/configure.in b/src/modules/_Image_TIFF/configure.in index dc2fd1509731995c009ae311a4e52aecec58be1e..3e1736d6198095dfb037af9cca8e8764d4259af4 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 aed221a8939e7c3e5675dd21462a8d853a05c8d0..f79642bd54d33b4065d3e023f43c91dc7272a815 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)) {