aboutsummaryrefslogtreecommitdiffstats
path: root/src/image.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/image.c')
-rw-r--r--src/image.c109
1 files changed, 102 insertions, 7 deletions
diff --git a/src/image.c b/src/image.c
index 2463c24a33a..1996d8477e9 100644
--- a/src/image.c
+++ b/src/image.c
@@ -1099,7 +1099,10 @@ or omitted means use the selected frame. */)
1099 1099
1100static struct image *make_image P_ ((Lisp_Object spec, unsigned hash)); 1100static struct image *make_image P_ ((Lisp_Object spec, unsigned hash));
1101static void free_image P_ ((struct frame *f, struct image *img)); 1101static void free_image P_ ((struct frame *f, struct image *img));
1102static int check_image_size P_ ((struct frame *f, int width, int height));
1102 1103
1104#define MAX_IMAGE_SIZE 6.0
1105Lisp_Object Vmax_image_size;
1103 1106
1104/* Allocate and return a new image structure for image specification 1107/* Allocate and return a new image structure for image specification
1105 SPEC. SPEC has a hash value of HASH. */ 1108 SPEC. SPEC has a hash value of HASH. */
@@ -1151,6 +1154,39 @@ free_image (f, img)
1151 } 1154 }
1152} 1155}
1153 1156
1157/* Return 1 if the given widths and heights are valid for display;
1158 otherwise, return 0. */
1159
1160int
1161check_image_size (f, width, height)
1162 struct frame *f;
1163 int width;
1164 int height;
1165{
1166 int w, h;
1167
1168 if (width <= 0 || height <= 0)
1169 return 0;
1170
1171 if (INTEGERP (Vmax_image_size))
1172 w = h = XINT (Vmax_image_size);
1173 else if (FLOATP (Vmax_image_size))
1174 {
1175 if (f != NULL)
1176 {
1177 w = FRAME_PIXEL_WIDTH (f);
1178 h = FRAME_PIXEL_HEIGHT (f);
1179 }
1180 else
1181 w = h = 1024; /* Arbitrary size for unknown frame. */
1182 w = (int) (XFLOAT_DATA (Vmax_image_size) * w);
1183 h = (int) (XFLOAT_DATA (Vmax_image_size) * h);
1184 }
1185 else
1186 return 1;
1187
1188 return (width <= w && height <= h);
1189}
1154 1190
1155/* Prepare image IMG for display on frame F. Must be called before 1191/* Prepare image IMG for display on frame F. Must be called before
1156 drawing an image. */ 1192 drawing an image. */
@@ -1708,6 +1744,12 @@ lookup_image (f, spec)
1708 if (img->hash == hash && !NILP (Fequal (img->spec, spec))) 1744 if (img->hash == hash && !NILP (Fequal (img->spec, spec)))
1709 break; 1745 break;
1710 1746
1747 if (img && img->load_failed_p)
1748 {
1749 free_image (f, img);
1750 img = NULL;
1751 }
1752
1711 /* If not found, create a new image and cache it. */ 1753 /* If not found, create a new image and cache it. */
1712 if (img == NULL) 1754 if (img == NULL)
1713 { 1755 {
@@ -2551,7 +2593,8 @@ static int xbm_load P_ ((struct frame *f, struct image *img));
2551static int xbm_load_image P_ ((struct frame *f, struct image *img, 2593static int xbm_load_image P_ ((struct frame *f, struct image *img,
2552 unsigned char *, unsigned char *)); 2594 unsigned char *, unsigned char *));
2553static int xbm_image_p P_ ((Lisp_Object object)); 2595static int xbm_image_p P_ ((Lisp_Object object));
2554static int xbm_read_bitmap_data P_ ((unsigned char *, unsigned char *, 2596static int xbm_read_bitmap_data P_ ((struct frame *f,
2597 unsigned char *, unsigned char *,
2555 int *, int *, unsigned char **)); 2598 int *, int *, unsigned char **));
2556static int xbm_file_p P_ ((Lisp_Object)); 2599static int xbm_file_p P_ ((Lisp_Object));
2557 2600
@@ -2939,7 +2982,8 @@ Create_Pixmap_From_Bitmap_Data(f, img, data, fg, bg, non_default_colors)
2939 CONTENTS looks like an in-memory XBM file. */ 2982 CONTENTS looks like an in-memory XBM file. */
2940 2983
2941static int 2984static int
2942xbm_read_bitmap_data (contents, end, width, height, data) 2985xbm_read_bitmap_data (f, contents, end, width, height, data)
2986 struct frame *f;
2943 unsigned char *contents, *end; 2987 unsigned char *contents, *end;
2944 int *width, *height; 2988 int *width, *height;
2945 unsigned char **data; 2989 unsigned char **data;
@@ -2992,7 +3036,7 @@ xbm_read_bitmap_data (contents, end, width, height, data)
2992 expect (XBM_TK_NUMBER); 3036 expect (XBM_TK_NUMBER);
2993 } 3037 }
2994 3038
2995 if (*width < 0 || *height < 0) 3039 if (!check_image_size (f, *width, *height))
2996 goto failure; 3040 goto failure;
2997 else if (data == NULL) 3041 else if (data == NULL)
2998 goto success; 3042 goto success;
@@ -3096,7 +3140,7 @@ xbm_load_image (f, img, contents, end)
3096 unsigned char *data; 3140 unsigned char *data;
3097 int success_p = 0; 3141 int success_p = 0;
3098 3142
3099 rc = xbm_read_bitmap_data (contents, end, &img->width, &img->height, &data); 3143 rc = xbm_read_bitmap_data (f, contents, end, &img->width, &img->height, &data);
3100 if (rc) 3144 if (rc)
3101 { 3145 {
3102 unsigned long foreground = FRAME_FOREGROUND_PIXEL (f); 3146 unsigned long foreground = FRAME_FOREGROUND_PIXEL (f);
@@ -3150,7 +3194,7 @@ xbm_file_p (data)
3150{ 3194{
3151 int w, h; 3195 int w, h;
3152 return (STRINGP (data) 3196 return (STRINGP (data)
3153 && xbm_read_bitmap_data (SDATA (data), 3197 && xbm_read_bitmap_data (NULL, SDATA (data),
3154 (SDATA (data) 3198 (SDATA (data)
3155 + SBYTES (data)), 3199 + SBYTES (data)),
3156 &w, &h, NULL)); 3200 &w, &h, NULL));
@@ -5465,8 +5509,7 @@ pbm_load (f, img)
5465 max_color_idx = 255; 5509 max_color_idx = 255;
5466 } 5510 }
5467 5511
5468 if (width < 0 5512 if (!check_image_size (f, width, height)
5469 || height < 0
5470 || (type != PBM_MONO && max_color_idx < 0)) 5513 || (type != PBM_MONO && max_color_idx < 0))
5471 goto error; 5514 goto error;
5472 5515
@@ -5966,6 +6009,9 @@ png_load (f, img)
5966 fn_png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 6009 fn_png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
5967 &interlace_type, NULL, NULL); 6010 &interlace_type, NULL, NULL);
5968 6011
6012 if (!check_image_size (f, width, height))
6013 goto error;
6014
5969 /* If image contains simply transparency data, we prefer to 6015 /* If image contains simply transparency data, we prefer to
5970 construct a clipping mask. */ 6016 construct a clipping mask. */
5971 if (fn_png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS)) 6017 if (fn_png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
@@ -6726,6 +6772,12 @@ jpeg_load (f, img)
6726 width = img->width = cinfo.output_width; 6772 width = img->width = cinfo.output_width;
6727 height = img->height = cinfo.output_height; 6773 height = img->height = cinfo.output_height;
6728 6774
6775 if (!check_image_size (f, width, height))
6776 {
6777 image_error ("Invalid image size", Qnil, Qnil);
6778 longjmp (mgr.setjmp_buffer, 2);
6779 }
6780
6729 /* Create X image and pixmap. */ 6781 /* Create X image and pixmap. */
6730 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) 6782 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
6731 longjmp (mgr.setjmp_buffer, 2); 6783 longjmp (mgr.setjmp_buffer, 2);
@@ -7155,6 +7207,14 @@ tiff_load (f, img)
7155 of width x height 32-bit values. */ 7207 of width x height 32-bit values. */
7156 fn_TIFFGetField (tiff, TIFFTAG_IMAGEWIDTH, &width); 7208 fn_TIFFGetField (tiff, TIFFTAG_IMAGEWIDTH, &width);
7157 fn_TIFFGetField (tiff, TIFFTAG_IMAGELENGTH, &height); 7209 fn_TIFFGetField (tiff, TIFFTAG_IMAGELENGTH, &height);
7210
7211 if (!check_image_size (f, width, height))
7212 {
7213 image_error ("Invalid image size", Qnil, Qnil);
7214 UNGCPRO;
7215 return 0;
7216 }
7217
7158 buf = (uint32 *) xmalloc (width * height * sizeof *buf); 7218 buf = (uint32 *) xmalloc (width * height * sizeof *buf);
7159 7219
7160 rc = fn_TIFFReadRGBAImage (tiff, width, height, buf, 0); 7220 rc = fn_TIFFReadRGBAImage (tiff, width, height, buf, 0);
@@ -7459,6 +7519,15 @@ gif_load (f, img)
7459 } 7519 }
7460 } 7520 }
7461 7521
7522 /* Before reading entire contents, check the declared image size. */
7523 if (!check_image_size (f, gif->SWidth, gif->SHeight))
7524 {
7525 image_error ("Invalid image size", Qnil, Qnil);
7526 fn_DGifCloseFile (gif);
7527 UNGCPRO;
7528 return 0;
7529 }
7530
7462 /* Read entire contents. */ 7531 /* Read entire contents. */
7463 rc = fn_DGifSlurp (gif); 7532 rc = fn_DGifSlurp (gif);
7464 if (rc == GIF_ERROR) 7533 if (rc == GIF_ERROR)
@@ -7492,6 +7561,14 @@ gif_load (f, img)
7492 max (gif->Image.Top + gif->Image.Height, 7561 max (gif->Image.Top + gif->Image.Height,
7493 image_top + image_height)); 7562 image_top + image_height));
7494 7563
7564 if (!check_image_size (f, width, height))
7565 {
7566 image_error ("Invalid image size", Qnil, Qnil);
7567 fn_DGifCloseFile (gif);
7568 UNGCPRO;
7569 return 0;
7570 }
7571
7495 /* Create the X image and pixmap. */ 7572 /* Create the X image and pixmap. */
7496 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap)) 7573 if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
7497 { 7574 {
@@ -7944,6 +8021,12 @@ gs_load (f, img)
7944 in_height = XFASTINT (pt_height) / 72.0; 8021 in_height = XFASTINT (pt_height) / 72.0;
7945 img->height = in_height * FRAME_X_DISPLAY_INFO (f)->resy; 8022 img->height = in_height * FRAME_X_DISPLAY_INFO (f)->resy;
7946 8023
8024 if (!check_image_size (f, img->width, img->height))
8025 {
8026 image_error ("Invalid image size", Qnil, Qnil);
8027 return 0;
8028 }
8029
7947 /* Create the pixmap. */ 8030 /* Create the pixmap. */
7948 xassert (img->pixmap == NO_PIXMAP); 8031 xassert (img->pixmap == NO_PIXMAP);
7949 8032
@@ -8217,6 +8300,18 @@ listed; they're always supported. */);
8217 Vimage_library_alist = Qnil; 8300 Vimage_library_alist = Qnil;
8218 Fput (intern ("image-library-alist"), Qrisky_local_variable, Qt); 8301 Fput (intern ("image-library-alist"), Qrisky_local_variable, Qt);
8219 8302
8303 DEFVAR_LISP ("max-image-size", &Vmax_image_size,
8304 doc: /* Maximum size of images.
8305Emacs will not load an image into memory if its pixel width or
8306pixel height exceeds this limit.
8307
8308If the value is an integer, it directly specifies the maximum
8309image height and width, measured in pixels. If it is a floating
8310point number, it specifies the maximum image height and width
8311as a ratio to the frame height and width. If the value is
8312non-numeric, there is no explicit limit on the size of images. */);
8313 Vmax_image_size = make_float (MAX_IMAGE_SIZE);
8314
8220 Vimage_type_cache = Qnil; 8315 Vimage_type_cache = Qnil;
8221 staticpro (&Vimage_type_cache); 8316 staticpro (&Vimage_type_cache);
8222 8317