From 5619f9e257ed0dcb80a5a229cb49981adc67b412 Mon Sep 17 00:00:00 2001 From: Kim Woelders Date: Mon, 27 Jul 2009 21:05:12 +0000 Subject: [PATCH] Relax 8192 pixel dimension limit (ticket 361). This time hopefully without buffer overflow issues. SVN revision: 41516 --- src/lib/Imlib2.h | 3 --- src/lib/image.h | 4 ++++ src/lib/rend.c | 5 +++-- src/modules/loaders/loader_argb.c | 2 +- src/modules/loaders/loader_bmp.c | 2 +- src/modules/loaders/loader_gif.c | 3 +-- src/modules/loaders/loader_jpeg.c | 4 ++-- src/modules/loaders/loader_lbm.c | 3 +-- src/modules/loaders/loader_png.c | 2 +- src/modules/loaders/loader_pnm.c | 2 +- src/modules/loaders/loader_tga.c | 3 +-- src/modules/loaders/loader_tiff.c | 3 +-- src/modules/loaders/loader_xpm.c | 16 +++------------- 13 files changed, 20 insertions(+), 32 deletions(-) diff --git a/src/lib/Imlib2.h b/src/lib/Imlib2.h index 3e2c5f2..e4008df 100644 --- a/src/lib/Imlib2.h +++ b/src/lib/Imlib2.h @@ -34,9 +34,6 @@ # define DATA8 unsigned char # endif -/* Maximum image dimension */ -#define IMLIB_MAX_DIM (2 << 20) - /* opaque data types */ typedef void *Imlib_Context; typedef void *Imlib_Image; diff --git a/src/lib/image.h b/src/lib/image.h index 49b93a4..b711047 100644 --- a/src/lib/image.h +++ b/src/lib/image.h @@ -188,4 +188,8 @@ __hidden void __imlib_SaveImage(ImlibImage *im, const char *file, # define SET_FLAG(flags, f) ((flags) |= (f)) # define UNSET_FLAG(flags, f) ((flags) &= (~f)) +# define IMAGE_DIMENSIONS_OK(w, h) \ + ( ((w) > 0) && ((h) > 0) && \ + ((unsigned long long)(w) * (unsigned long long)(w) <= (1ULL << 31) - 1) ) + #endif diff --git a/src/lib/rend.c b/src/lib/rend.c index bef019c..33f17a2 100644 --- a/src/lib/rend.c +++ b/src/lib/rend.c @@ -15,8 +15,9 @@ #include "rend.h" #include "rotate.h" -/* Maximum pixmap dimension (65535) */ -#define X_MAX_DIM ((2 << 16) - 1) +/* The maximum pixmap dimension is 65535. */ +/* However, for now, use 46340 (46340^2 < 2^31) to avoid buffer overflow issues. */ +#define X_MAX_DIM 46340 /* size of the lines per segment we scale / render at a time */ #define LINESIZE 16 diff --git a/src/modules/loaders/loader_argb.c b/src/modules/loaders/loader_argb.c index 709c60b..20aae35 100644 --- a/src/modules/loaders/loader_argb.c +++ b/src/modules/loaders/loader_argb.c @@ -36,7 +36,7 @@ load(ImlibImage * im, ImlibProgressFunction progress, fclose(f); return 0; } - if ((w < 1) || (h < 1) || (w > IMLIB_MAX_DIM) || (h > IMLIB_MAX_DIM)) + if (!IMAGE_DIMENSIONS_OK(w, h)) { fclose(f); return 0; diff --git a/src/modules/loaders/loader_bmp.c b/src/modules/loaders/loader_bmp.c index 98a3b5e..87792e7 100644 --- a/src/modules/loaders/loader_bmp.c +++ b/src/modules/loaders/loader_bmp.c @@ -193,7 +193,7 @@ load(ImlibImage * im, ImlibProgressFunction progress, return 0; } - if ((w < 1) || (h < 1) || (w > IMLIB_MAX_DIM) || (h > IMLIB_MAX_DIM)) + if (!IMAGE_DIMENSIONS_OK(w, h)) { fclose(f); return 0; diff --git a/src/modules/loaders/loader_gif.c b/src/modules/loaders/loader_gif.c index 10245ce..4337826 100644 --- a/src/modules/loaders/loader_gif.c +++ b/src/modules/loaders/loader_gif.c @@ -58,8 +58,7 @@ load(ImlibImage * im, ImlibProgressFunction progress, char progress_granularity, } w = gif->Image.Width; h = gif->Image.Height; - if ((w < 1) || (h < 1) || - (w > IMLIB_MAX_DIM) || (h > IMLIB_MAX_DIM)) + if (!IMAGE_DIMENSIONS_OK(w, h)) { DGifCloseFile(gif); return 0; diff --git a/src/modules/loaders/loader_jpeg.c b/src/modules/loaders/loader_jpeg.c index c7cc0b8..085f368 100644 --- a/src/modules/loaders/loader_jpeg.c +++ b/src/modules/loaders/loader_jpeg.c @@ -76,7 +76,7 @@ load(ImlibImage * im, ImlibProgressFunction progress, { im->w = w = cinfo.output_width; im->h = h = cinfo.output_height; - if ((w < 1) || (h < 1) || (w > IMLIB_MAX_DIM) || (h > IMLIB_MAX_DIM)) + if (!IMAGE_DIMENSIONS_OK(w, h)) { im->w = im->h = 0; jpeg_destroy_decompress(&cinfo); @@ -96,7 +96,7 @@ load(ImlibImage * im, ImlibProgressFunction progress, im->h = h = cinfo.output_height; if ((cinfo.rec_outbuf_height > 16) || (cinfo.output_components <= 0) || - (w < 1) || (h < 1) || (w > IMLIB_MAX_DIM) || (h > IMLIB_MAX_DIM)) + !IMAGE_DIMENSIONS_OK(w, h)) { im->w = im->h = 0; jpeg_destroy_decompress(&cinfo); diff --git a/src/modules/loaders/loader_lbm.c b/src/modules/loaders/loader_lbm.c index 878e4b1..6a869ce 100644 --- a/src/modules/loaders/loader_lbm.c +++ b/src/modules/loaders/loader_lbm.c @@ -402,8 +402,7 @@ ILBM ilbm; im->w = L2RWORD(ilbm.bmhd.data); im->h = L2RWORD(ilbm.bmhd.data + 2); - if ((im->w < 1) || (im->h < 1) || - (im->w > IMLIB_MAX_DIM) || (im->h > IMLIB_MAX_DIM)) + if (!IMAGE_DIMENSIONS_OK(im->w, im->h)) { ok = 0; } diff --git a/src/modules/loaders/loader_png.c b/src/modules/loaders/loader_png.c index 60d32dd..2a34bd8 100644 --- a/src/modules/loaders/loader_png.c +++ b/src/modules/loaders/loader_png.c @@ -71,7 +71,7 @@ load(ImlibImage * im, ImlibProgressFunction progress, &interlace_type, NULL, NULL); im->w = (int)w32; im->h = (int)h32; - if ((w32 < 1) || (h32 < 1) || (w32 > IMLIB_MAX_DIM) || (h32 > IMLIB_MAX_DIM)) + if (!IMAGE_DIMENSIONS_OK(w32, h32)) { png_read_end(png_ptr, info_ptr); png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp) NULL); diff --git a/src/modules/loaders/loader_pnm.c b/src/modules/loaders/loader_pnm.c index b29b2f7..c77628e 100644 --- a/src/modules/loaders/loader_pnm.c +++ b/src/modules/loaders/loader_pnm.c @@ -103,7 +103,7 @@ load(ImlibImage * im, ImlibProgressFunction progress, im->w = w; im->h = h; - if ((w < 1) || (h < 1) || (w > IMLIB_MAX_DIM) || (h > IMLIB_MAX_DIM)) + if (!IMAGE_DIMENSIONS_OK(w, h)) { fclose(f); return 0; diff --git a/src/modules/loaders/loader_tga.c b/src/modules/loaders/loader_tga.c index 6228d01..2070166 100644 --- a/src/modules/loaders/loader_tga.c +++ b/src/modules/loaders/loader_tga.c @@ -283,8 +283,7 @@ load(ImlibImage * im, ImlibProgressFunction progress, im->w = (header->widthHi << 8) | header->widthLo; im->h = (header->heightHi << 8) | header->heightLo; - if ((im->w < 1) || (im->h < 1) || - (im->w > IMLIB_MAX_DIM) || (im->h > IMLIB_MAX_DIM)) + if (!IMAGE_DIMENSIONS_OK(im->w, im->h)) { munmap(seg, ss.st_size); close(fd); diff --git a/src/modules/loaders/loader_tiff.c b/src/modules/loaders/loader_tiff.c index 799c360..d26e0f6 100644 --- a/src/modules/loaders/loader_tiff.c +++ b/src/modules/loaders/loader_tiff.c @@ -184,8 +184,7 @@ load(ImlibImage * im, ImlibProgressFunction progress, rgba_image.image = im; im->w = width = rgba_image.rgba.width; im->h = height = rgba_image.rgba.height; - if ((width < 1) || (height < 1) || - (width > IMLIB_MAX_DIM) || (height > IMLIB_MAX_DIM)) + if (!IMAGE_DIMENSIONS_OK(width, height)) { TIFFRGBAImageEnd((TIFFRGBAImage *) & rgba_image); TIFFClose(tif); diff --git a/src/modules/loaders/loader_xpm.c b/src/modules/loaders/loader_xpm.c index 73ddbcc..4a594d0 100644 --- a/src/modules/loaders/loader_xpm.c +++ b/src/modules/loaders/loader_xpm.c @@ -204,21 +204,11 @@ load(ImlibImage * im, ImlibProgressFunction progress, char progress_granularity, xpm_parse_done(); return 0; } - if ((w > IMLIB_MAX_DIM) || (w < 1)) + if (!IMAGE_DIMENSIONS_OK(w, h)) { fprintf(stderr, - "IMLIB ERROR: Image width > %d or < 1 pixels for file\n", - IMLIB_MAX_DIM); - free(line); - fclose(f); - xpm_parse_done(); - return 0; - } - if ((h > IMLIB_MAX_DIM) || (h < 1)) - { - fprintf(stderr, - "IMLIB ERROR: Image height > %d or < 1 pixels for file\n", - IMLIB_MAX_DIM); + "IMLIB ERROR: Invalid image dimension: %dx%d\n", + w, h); free(line); fclose(f); xpm_parse_done();