# HG changeset patch # User Chong Yidong # Date 1129694096 0 # Node ID ad1acaef1abbdbe69f57e9688f805b10f9646ff1 # Parent 6b43bb0a3a9cd42c0ad054a63cd3288bed21b9d7 * image.c (Vmax_image_size): New variable. (check_image_size): New function. (xbm_read_bitmap_data, pbm_load, png_load, jpeg_load, tiff_load) (gif_load, gs_load): Use it. (lookup_image): Try loading again if previous load failed. (xbm_read_bitmap_data): Add a new argument, a pointer to the frame to display in, NULL if none. (xbm_load_image, xbm_file_p): Pass xbm_read_bitmap_data the new argument. diff -r 6b43bb0a3a9c -r ad1acaef1abb src/ChangeLog --- a/src/ChangeLog Wed Oct 19 01:52:59 2005 +0000 +++ b/src/ChangeLog Wed Oct 19 03:54:56 2005 +0000 @@ -1,3 +1,15 @@ +2005-10-18 Chong Yidong + + * image.c (Vmax_image_size): New variable. + (check_image_size): New function. + (xbm_read_bitmap_data, pbm_load, png_load, jpeg_load, tiff_load) + (gif_load, gs_load): Use it. + (lookup_image): Try loading again if previous load failed. + (xbm_read_bitmap_data): Add a new argument, a pointer to the frame + to display in, NULL if none. + (xbm_load_image, xbm_file_p): Pass xbm_read_bitmap_data the new + argument. + 2005-10-18 Richard M. Stallman * search.c (Fstring_match): Doc fix. diff -r 6b43bb0a3a9c -r ad1acaef1abb src/image.c --- a/src/image.c Wed Oct 19 01:52:59 2005 +0000 +++ b/src/image.c Wed Oct 19 03:54:56 2005 +0000 @@ -1099,7 +1099,10 @@ static struct image *make_image P_ ((Lisp_Object spec, unsigned hash)); static void free_image P_ ((struct frame *f, struct image *img)); - +static int check_image_size P_ ((struct frame *f, int width, int height)); + +#define MAX_IMAGE_SIZE 6.0 +Lisp_Object Vmax_image_size; /* Allocate and return a new image structure for image specification SPEC. SPEC has a hash value of HASH. */ @@ -1151,6 +1154,27 @@ } } +/* Return 1 if the given widths and heights are valid for display; + otherwise, return 0. */ + +int +check_image_size (f, width, height) + struct frame *f; + int width; + int height; +{ + if (width <= 0 || height <=0) + return 0; + + if (FLOATP (Vmax_image_size) && f + && ((width > (int)(XFLOAT_DATA (Vmax_image_size) + * FRAME_PIXEL_WIDTH (f))) + || (height > (int)(XFLOAT_DATA (Vmax_image_size) + * FRAME_PIXEL_HEIGHT (f))))) + return 0; + + return 1; +} /* Prepare image IMG for display on frame F. Must be called before drawing an image. */ @@ -1708,6 +1732,12 @@ if (img->hash == hash && !NILP (Fequal (img->spec, spec))) break; + if (img && img->load_failed_p) + { + free_image (f, img); + img = NULL; + } + /* If not found, create a new image and cache it. */ if (img == NULL) { @@ -2551,7 +2581,8 @@ static int xbm_load_image P_ ((struct frame *f, struct image *img, unsigned char *, unsigned char *)); static int xbm_image_p P_ ((Lisp_Object object)); -static int xbm_read_bitmap_data P_ ((unsigned char *, unsigned char *, +static int xbm_read_bitmap_data P_ ((struct frame *f, + unsigned char *, unsigned char *, int *, int *, unsigned char **)); static int xbm_file_p P_ ((Lisp_Object)); @@ -2939,7 +2970,8 @@ CONTENTS looks like an in-memory XBM file. */ static int -xbm_read_bitmap_data (contents, end, width, height, data) +xbm_read_bitmap_data (f, contents, end, width, height, data) + struct frame *f; unsigned char *contents, *end; int *width, *height; unsigned char **data; @@ -2992,7 +3024,7 @@ expect (XBM_TK_NUMBER); } - if (*width < 0 || *height < 0) + if (!check_image_size (f, *width, *height)) goto failure; else if (data == NULL) goto success; @@ -3096,7 +3128,7 @@ unsigned char *data; int success_p = 0; - rc = xbm_read_bitmap_data (contents, end, &img->width, &img->height, &data); + rc = xbm_read_bitmap_data (f, contents, end, &img->width, &img->height, &data); if (rc) { unsigned long foreground = FRAME_FOREGROUND_PIXEL (f); @@ -3150,7 +3182,7 @@ { int w, h; return (STRINGP (data) - && xbm_read_bitmap_data (SDATA (data), + && xbm_read_bitmap_data (NULL, SDATA (data), (SDATA (data) + SBYTES (data)), &w, &h, NULL)); @@ -5465,8 +5497,7 @@ max_color_idx = 255; } - if (width < 0 - || height < 0 + if (!check_image_size (f, width, height) || (type != PBM_MONO && max_color_idx < 0)) goto error; @@ -5966,6 +5997,9 @@ fn_png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL); + if (!check_image_size (f, width, height)) + goto error; + /* If image contains simply transparency data, we prefer to construct a clipping mask. */ if (fn_png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS)) @@ -6726,6 +6760,12 @@ width = img->width = cinfo.output_width; height = img->height = cinfo.output_height; + if (!check_image_size (f, width, height)) + { + image_error ("Invalid image size", Qnil, Qnil); + longjmp (mgr.setjmp_buffer, 2); + } + /* Create X image and pixmap. */ if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) longjmp (mgr.setjmp_buffer, 2); @@ -7155,6 +7195,14 @@ of width x height 32-bit values. */ fn_TIFFGetField (tiff, TIFFTAG_IMAGEWIDTH, &width); fn_TIFFGetField (tiff, TIFFTAG_IMAGELENGTH, &height); + + if (!check_image_size (f, width, height)) + { + image_error ("Invalid image size", Qnil, Qnil); + UNGCPRO; + return 0; + } + buf = (uint32 *) xmalloc (width * height * sizeof *buf); rc = fn_TIFFReadRGBAImage (tiff, width, height, buf, 0); @@ -7459,6 +7507,15 @@ } } + /* Before reading entire contents, check the declared image size. */ + if (!check_image_size (f, gif->SWidth, gif->SHeight)) + { + image_error ("Invalid image size", Qnil, Qnil); + fn_DGifCloseFile (gif); + UNGCPRO; + return 0; + } + /* Read entire contents. */ rc = fn_DGifSlurp (gif); if (rc == GIF_ERROR) @@ -7492,6 +7549,14 @@ max (gif->Image.Top + gif->Image.Height, image_top + image_height)); + if (!check_image_size (f, width, height)) + { + image_error ("Invalid image size", Qnil, Qnil); + fn_DGifCloseFile (gif); + UNGCPRO; + return 0; + } + /* Create the X image and pixmap. */ if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) { @@ -7944,6 +8009,12 @@ in_height = XFASTINT (pt_height) / 72.0; img->height = in_height * FRAME_X_DISPLAY_INFO (f)->resy; + if (!check_image_size (f, img->width, img->height)) + { + image_error ("Invalid image size", Qnil, Qnil); + return 0; + } + /* Create the pixmap. */ xassert (img->pixmap == NO_PIXMAP); @@ -8217,6 +8288,15 @@ Vimage_library_alist = Qnil; Fput (intern ("image-library-alist"), Qrisky_local_variable, Qt); + DEFVAR_LISP ("max-image-size", &Vmax_image_size, + doc: /* Maximum size of an image, relative to the selected frame. + +This is a floating point number that is multiplied by the width and +height of the selected frame, to give the maximum width and height for +images. Emacs will not load an image into memory if its width or +height exceeds this limit. */); + Vmax_image_size = make_float (MAX_IMAGE_SIZE); + Vimage_type_cache = Qnil; staticpro (&Vimage_type_cache);