summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChong Yidong <cyd@stupidchicken.com>2005-10-19 03:54:56 +0000
committerChong Yidong <cyd@stupidchicken.com>2005-10-19 03:54:56 +0000
commitf1f25b99665ac3e5cd4c6cf70be8fdf637f10b52 (patch)
tree66f91ab3a7adf9a3ed66938d90a3da4674d916d0 /src
parentf42d19a283c2888320519c78093de6a788374634 (diff)
downloademacs-f1f25b99665ac3e5cd4c6cf70be8fdf637f10b52.tar.gz
* 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.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog12
-rw-r--r--src/image.c94
2 files changed, 99 insertions, 7 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 40d2ed10308..852a7b9745e 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,15 @@
+2005-10-18 Chong Yidong <cyd@stupidchicken.com>
+
+ * 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 <rms@gnu.org>
* search.c (Fstring_match): Doc fix.
diff --git a/src/image.c b/src/image.c
index 2463c24a33a..c0702c5ea8c 100644
--- a/src/image.c
+++ b/src/image.c
@@ -1099,7 +1099,10 @@ or omitted means use the selected frame. */)
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 @@ free_image (f, img)
}
}
+/* 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 @@ lookup_image (f, spec)
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 P_ ((struct frame *f, struct image *img));
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 @@ Create_Pixmap_From_Bitmap_Data(f, img, data, fg, bg, non_default_colors)
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 @@ xbm_read_bitmap_data (contents, end, width, height, data)
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 @@ xbm_load_image (f, img, contents, end)
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 @@ xbm_file_p (data)
{
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 @@ pbm_load (f, img)
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 @@ png_load (f, img)
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 @@ jpeg_load (f, img)
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 @@ tiff_load (f, img)
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 @@ gif_load (f, img)
}
}
+ /* 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 @@ gif_load (f, img)
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 @@ gs_load (f, img)
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 @@ listed; they're always supported. */);
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);