aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2011-07-09 00:01:24 -0700
committerPaul Eggert2011-07-09 00:01:24 -0700
commit3f791afed9cd1002b909cefd3482763b2a310608 (patch)
treecda22ac880a1ea3aaf79c03c1f3352212ee4d10c /src
parent3cc5a5328c43317b12a7163c4e1c0a56d85b93ce (diff)
downloademacs-3f791afed9cd1002b909cefd3482763b2a310608.tar.gz
emacs-3f791afed9cd1002b909cefd3482763b2a310608.zip
* image.c: Integer signedness and overflow and related fixes.
This is not an exhaustive set of fixes, but it's time to record what I've got. (lookup_pixel_color, check_image_size): Remove redundant decls. (check_image_size): Don't assume that arbitrary EMACS_INT values fit in 'int', or that arbitrary 'double' values fit in 'int'. (x_alloc_image_color, x_create_x_image_and_pixmap, png_load) (tiff_load, imagemagick_load_image): Check for overflow in size calculations. (x_create_x_image_and_pixmap): Remove unnecessary test for xmalloc returning NULL; that can't happen. (xbm_read_bitmap_data): Don't assume sizes fit into 'int'. (xpm_color_bucket): Use better integer hashing function. (xpm_cache_color): Don't possibly over-allocate memory. (struct png_memory_storage, tiff_memory_source, tiff_seek_in_memory) (gif_memory_source): Use ptrdiff_t, not int or size_t, to record sizes. (png_load): Don't assume values greater than 2**31 fit in 'int'. (our_stdio_fill_input_buffer): Prefer ptrdiff_t to size_t when either works, as we prefer signed integers. (tiff_read_from_memory, tiff_write_from_memory): Return tsize_t, not size_t, since that's what the TIFF API wants. (tiff_read_from_memory): Don't fail simply because the read would go past EOF; instead, return a short read. (tiff_load): Omit no-longer-needed casts. (Fimagemagick_types): Don't assume size fits into 'int'.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog29
-rw-r--r--src/image.c85
2 files changed, 72 insertions, 42 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index aaf87deb9a5..d7ee434378c 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,32 @@
12011-07-09 Paul Eggert <eggert@cs.ucla.edu>
2
3 * image.c: Integer signedness and overflow and related fixes.
4 This is not an exhaustive set of fixes, but it's time to
5 record what I've got.
6 (lookup_pixel_color, check_image_size): Remove redundant decls.
7 (check_image_size): Don't assume that arbitrary EMACS_INT values
8 fit in 'int', or that arbitrary 'double' values fit in 'int'.
9 (x_alloc_image_color, x_create_x_image_and_pixmap, png_load)
10 (tiff_load, imagemagick_load_image):
11 Check for overflow in size calculations.
12 (x_create_x_image_and_pixmap): Remove unnecessary test for
13 xmalloc returning NULL; that can't happen.
14 (xbm_read_bitmap_data): Don't assume sizes fit into 'int'.
15 (xpm_color_bucket): Use better integer hashing function.
16 (xpm_cache_color): Don't possibly over-allocate memory.
17 (struct png_memory_storage, tiff_memory_source, tiff_seek_in_memory)
18 (gif_memory_source):
19 Use ptrdiff_t, not int or size_t, to record sizes.
20 (png_load): Don't assume values greater than 2**31 fit in 'int'.
21 (our_stdio_fill_input_buffer): Prefer ptrdiff_t to size_t when
22 either works, as we prefer signed integers.
23 (tiff_read_from_memory, tiff_write_from_memory):
24 Return tsize_t, not size_t, since that's what the TIFF API wants.
25 (tiff_read_from_memory): Don't fail simply because the read would
26 go past EOF; instead, return a short read.
27 (tiff_load): Omit no-longer-needed casts.
28 (Fimagemagick_types): Don't assume size fits into 'int'.
29
12011-07-08 Paul Eggert <eggert@cs.ucla.edu> 302011-07-08 Paul Eggert <eggert@cs.ucla.edu>
2 31
3 Improve hashing quality when configured --with-wide-int. 32 Improve hashing quality when configured --with-wide-int.
diff --git a/src/image.c b/src/image.c
index 6e8440fb431..a09fc7a8979 100644
--- a/src/image.c
+++ b/src/image.c
@@ -136,7 +136,6 @@ static unsigned long lookup_rgb_color (struct frame *f, int r, int g, int b);
136#ifdef COLOR_TABLE_SUPPORT 136#ifdef COLOR_TABLE_SUPPORT
137static void free_color_table (void); 137static void free_color_table (void);
138static unsigned long *colors_in_color_table (int *n); 138static unsigned long *colors_in_color_table (int *n);
139static unsigned long lookup_pixel_color (struct frame *f, unsigned long p);
140#endif 139#endif
141static Lisp_Object Finit_image_library (Lisp_Object, Lisp_Object); 140static Lisp_Object Finit_image_library (Lisp_Object, Lisp_Object);
142 141
@@ -987,7 +986,6 @@ or omitted means use the selected frame. */)
987 ***********************************************************************/ 986 ***********************************************************************/
988 987
989static void free_image (struct frame *f, struct image *img); 988static void free_image (struct frame *f, struct image *img);
990static int check_image_size (struct frame *f, int width, int height);
991 989
992#define MAX_IMAGE_SIZE 6.0 990#define MAX_IMAGE_SIZE 6.0
993/* Allocate and return a new image structure for image specification 991/* Allocate and return a new image structure for image specification
@@ -1042,7 +1040,7 @@ free_image (struct frame *f, struct image *img)
1042/* Return 1 if the given widths and heights are valid for display; 1040/* Return 1 if the given widths and heights are valid for display;
1043 otherwise, return 0. */ 1041 otherwise, return 0. */
1044 1042
1045int 1043static int
1046check_image_size (struct frame *f, int width, int height) 1044check_image_size (struct frame *f, int width, int height)
1047{ 1045{
1048 int w, h; 1046 int w, h;
@@ -1051,7 +1049,8 @@ check_image_size (struct frame *f, int width, int height)
1051 return 0; 1049 return 0;
1052 1050
1053 if (INTEGERP (Vmax_image_size)) 1051 if (INTEGERP (Vmax_image_size))
1054 w = h = XINT (Vmax_image_size); 1052 return (width <= XINT (Vmax_image_size)
1053 && height <= XINT (Vmax_image_size));
1055 else if (FLOATP (Vmax_image_size)) 1054 else if (FLOATP (Vmax_image_size))
1056 { 1055 {
1057 if (f != NULL) 1056 if (f != NULL)
@@ -1061,13 +1060,11 @@ check_image_size (struct frame *f, int width, int height)
1061 } 1060 }
1062 else 1061 else
1063 w = h = 1024; /* Arbitrary size for unknown frame. */ 1062 w = h = 1024; /* Arbitrary size for unknown frame. */
1064 w = (int) (XFLOAT_DATA (Vmax_image_size) * w); 1063 return (width <= XFLOAT_DATA (Vmax_image_size) * w
1065 h = (int) (XFLOAT_DATA (Vmax_image_size) * h); 1064 && height <= XFLOAT_DATA (Vmax_image_size) * h);
1066 } 1065 }
1067 else 1066 else
1068 return 1; 1067 return 1;
1069
1070 return (width <= w && height <= h);
1071} 1068}
1072 1069
1073/* Prepare image IMG for display on frame F. Must be called before 1070/* Prepare image IMG for display on frame F. Must be called before
@@ -1368,7 +1365,9 @@ x_alloc_image_color (struct frame *f, struct image *img, Lisp_Object color_name,
1368 1365
1369 xassert (STRINGP (color_name)); 1366 xassert (STRINGP (color_name));
1370 1367
1371 if (x_defined_color (f, SSDATA (color_name), &color, 1)) 1368 if (x_defined_color (f, SSDATA (color_name), &color, 1)
1369 && img->ncolors < min (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *img->colors,
1370 INT_MAX))
1372 { 1371 {
1373 /* This isn't called frequently so we get away with simply 1372 /* This isn't called frequently so we get away with simply
1374 reallocating the color vector to the needed size, here. */ 1373 reallocating the color vector to the needed size, here. */
@@ -1944,6 +1943,8 @@ x_create_x_image_and_pixmap (struct frame *f, int width, int height, int depth,
1944 } 1943 }
1945 1944
1946 /* Allocate image raster. */ 1945 /* Allocate image raster. */
1946 if (min (PTRDIFF_MAX, SIZE_MAX) / height < (*ximg)->bytes_per_line)
1947 memory_full (SIZE_MAX);
1947 (*ximg)->data = (char *) xmalloc ((*ximg)->bytes_per_line * height); 1948 (*ximg)->data = (char *) xmalloc ((*ximg)->bytes_per_line * height);
1948 1949
1949 /* Allocate a pixmap of the same size. */ 1950 /* Allocate a pixmap of the same size. */
@@ -1989,11 +1990,6 @@ x_create_x_image_and_pixmap (struct frame *f, int width, int height, int depth,
1989 palette_colors = 1 << depth - 1; 1990 palette_colors = 1 << depth - 1;
1990 1991
1991 *ximg = xmalloc (sizeof (XImage) + palette_colors * sizeof (RGBQUAD)); 1992 *ximg = xmalloc (sizeof (XImage) + palette_colors * sizeof (RGBQUAD));
1992 if (*ximg == NULL)
1993 {
1994 image_error ("Unable to allocate memory for XImage", Qnil, Qnil);
1995 return 0;
1996 }
1997 1993
1998 header = &(*ximg)->info.bmiHeader; 1994 header = &(*ximg)->info.bmiHeader;
1999 memset (&(*ximg)->info, 0, sizeof (BITMAPINFO)); 1995 memset (&(*ximg)->info, 0, sizeof (BITMAPINFO));
@@ -2591,7 +2587,8 @@ xbm_read_bitmap_data (struct frame *f, unsigned char *contents, unsigned char *e
2591 char buffer[BUFSIZ]; 2587 char buffer[BUFSIZ];
2592 int padding_p = 0; 2588 int padding_p = 0;
2593 int v10 = 0; 2589 int v10 = 0;
2594 int bytes_per_line, i, nbytes; 2590 int bytes_per_line;
2591 ptrdiff_t i, nbytes;
2595 char *p; 2592 char *p;
2596 int value; 2593 int value;
2597 int LA1; 2594 int LA1;
@@ -2675,6 +2672,8 @@ xbm_read_bitmap_data (struct frame *f, unsigned char *contents, unsigned char *e
2675 expect ('{'); 2672 expect ('{');
2676 2673
2677 bytes_per_line = (*width + 7) / 8 + padding_p; 2674 bytes_per_line = (*width + 7) / 8 + padding_p;
2675 if (min (PTRDIFF_MAX - 1, SIZE_MAX) / *height < bytes_per_line)
2676 memory_full (SIZE_MAX);
2678 nbytes = bytes_per_line * *height; 2677 nbytes = bytes_per_line * *height;
2679 p = *data = (char *) xmalloc (nbytes); 2678 p = *data = (char *) xmalloc (nbytes);
2680 2679
@@ -3125,12 +3124,8 @@ xpm_free_color_cache (void)
3125static int 3124static int
3126xpm_color_bucket (char *color_name) 3125xpm_color_bucket (char *color_name)
3127{ 3126{
3128 unsigned h = 0; 3127 EMACS_UINT hash = hash_string (color_name, strlen (color_name));
3129 char *s; 3128 return hash % XPM_COLOR_CACHE_BUCKETS;
3130
3131 for (s = color_name; *s; ++s)
3132 h = (h << 2) ^ *s;
3133 return h %= XPM_COLOR_CACHE_BUCKETS;
3134} 3129}
3135 3130
3136 3131
@@ -3147,7 +3142,7 @@ xpm_cache_color (struct frame *f, char *color_name, XColor *color, int bucket)
3147 if (bucket < 0) 3142 if (bucket < 0)
3148 bucket = xpm_color_bucket (color_name); 3143 bucket = xpm_color_bucket (color_name);
3149 3144
3150 nbytes = sizeof *p + strlen (color_name); 3145 nbytes = offsetof (struct xpm_cached_color, name) + strlen (color_name) + 1;
3151 p = (struct xpm_cached_color *) xmalloc (nbytes); 3146 p = (struct xpm_cached_color *) xmalloc (nbytes);
3152 strcpy (p->name, color_name); 3147 strcpy (p->name, color_name);
3153 p->color = *color; 3148 p->color = *color;
@@ -5520,8 +5515,8 @@ my_png_warning (png_struct *png_ptr, const char *msg)
5520struct png_memory_storage 5515struct png_memory_storage
5521{ 5516{
5522 unsigned char *bytes; /* The data */ 5517 unsigned char *bytes; /* The data */
5523 size_t len; /* How big is it? */ 5518 ptrdiff_t len; /* How big is it? */
5524 int index; /* Where are we? */ 5519 ptrdiff_t index; /* Where are we? */
5525}; 5520};
5526 5521
5527 5522
@@ -5685,7 +5680,8 @@ png_load (struct frame *f, struct image *img)
5685 fn_png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, 5680 fn_png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
5686 &interlace_type, NULL, NULL); 5681 &interlace_type, NULL, NULL);
5687 5682
5688 if (!check_image_size (f, width, height)) 5683 if (! (width <= INT_MAX && height <= INT_MAX
5684 && check_image_size (f, width, height)))
5689 { 5685 {
5690 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil); 5686 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
5691 goto error; 5687 goto error;
@@ -5778,7 +5774,10 @@ png_load (struct frame *f, struct image *img)
5778 row_bytes = fn_png_get_rowbytes (png_ptr, info_ptr); 5774 row_bytes = fn_png_get_rowbytes (png_ptr, info_ptr);
5779 5775
5780 /* Allocate memory for the image. */ 5776 /* Allocate memory for the image. */
5781 pixels = (png_byte *) xmalloc (row_bytes * height * sizeof *pixels); 5777 if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *rows < height
5778 || min (PTRDIFF_MAX, SIZE_MAX) / sizeof *pixels / height < row_bytes)
5779 memory_full (SIZE_MAX);
5780 pixels = (png_byte *) xmalloc (sizeof *pixels * row_bytes * height);
5782 rows = (png_byte **) xmalloc (height * sizeof *rows); 5781 rows = (png_byte **) xmalloc (height * sizeof *rows);
5783 for (i = 0; i < height; ++i) 5782 for (i = 0; i < height; ++i)
5784 rows[i] = pixels + i * row_bytes; 5783 rows[i] = pixels + i * row_bytes;
@@ -6194,7 +6193,7 @@ our_stdio_fill_input_buffer (j_decompress_ptr cinfo)
6194 src = (struct jpeg_stdio_mgr *) cinfo->src; 6193 src = (struct jpeg_stdio_mgr *) cinfo->src;
6195 if (!src->finished) 6194 if (!src->finished)
6196 { 6195 {
6197 size_t bytes; 6196 ptrdiff_t bytes;
6198 6197
6199 bytes = fread (src->buffer, 1, JPEG_STDIO_BUFFER_SIZE, src->file); 6198 bytes = fread (src->buffer, 1, JPEG_STDIO_BUFFER_SIZE, src->file);
6200 if (bytes > 0) 6199 if (bytes > 0)
@@ -6604,34 +6603,33 @@ init_tiff_functions (Lisp_Object libraries)
6604typedef struct 6603typedef struct
6605{ 6604{
6606 unsigned char *bytes; 6605 unsigned char *bytes;
6607 size_t len; 6606 ptrdiff_t len;
6608 int index; 6607 ptrdiff_t index;
6609} 6608}
6610tiff_memory_source; 6609tiff_memory_source;
6611 6610
6612static size_t 6611static tsize_t
6613tiff_read_from_memory (thandle_t data, tdata_t buf, tsize_t size) 6612tiff_read_from_memory (thandle_t data, tdata_t buf, tsize_t size)
6614{ 6613{
6615 tiff_memory_source *src = (tiff_memory_source *) data; 6614 tiff_memory_source *src = (tiff_memory_source *) data;
6616 6615
6617 if (size > src->len - src->index) 6616 size = min (size, src->len - src->index);
6618 return (size_t) -1;
6619 memcpy (buf, src->bytes + src->index, size); 6617 memcpy (buf, src->bytes + src->index, size);
6620 src->index += size; 6618 src->index += size;
6621 return size; 6619 return size;
6622} 6620}
6623 6621
6624static size_t 6622static tsize_t
6625tiff_write_from_memory (thandle_t data, tdata_t buf, tsize_t size) 6623tiff_write_from_memory (thandle_t data, tdata_t buf, tsize_t size)
6626{ 6624{
6627 return (size_t) -1; 6625 return -1;
6628} 6626}
6629 6627
6630static toff_t 6628static toff_t
6631tiff_seek_in_memory (thandle_t data, toff_t off, int whence) 6629tiff_seek_in_memory (thandle_t data, toff_t off, int whence)
6632{ 6630{
6633 tiff_memory_source *src = (tiff_memory_source *) data; 6631 tiff_memory_source *src = (tiff_memory_source *) data;
6634 int idx; 6632 ptrdiff_t idx;
6635 6633
6636 switch (whence) 6634 switch (whence)
6637 { 6635 {
@@ -6767,8 +6765,8 @@ tiff_load (struct frame *f, struct image *img)
6767 memsrc.index = 0; 6765 memsrc.index = 0;
6768 6766
6769 tiff = fn_TIFFClientOpen ("memory_source", "r", (thandle_t)&memsrc, 6767 tiff = fn_TIFFClientOpen ("memory_source", "r", (thandle_t)&memsrc,
6770 (TIFFReadWriteProc) tiff_read_from_memory, 6768 tiff_read_from_memory,
6771 (TIFFReadWriteProc) tiff_write_from_memory, 6769 tiff_write_from_memory,
6772 tiff_seek_in_memory, 6770 tiff_seek_in_memory,
6773 tiff_close_memory, 6771 tiff_close_memory,
6774 tiff_size_of_memory, 6772 tiff_size_of_memory,
@@ -6807,7 +6805,9 @@ tiff_load (struct frame *f, struct image *img)
6807 return 0; 6805 return 0;
6808 } 6806 }
6809 6807
6810 buf = (uint32 *) xmalloc (width * height * sizeof *buf); 6808 if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *buf / width < height)
6809 memory_full (SIZE_MAX);
6810 buf = (uint32 *) xmalloc (sizeof *buf * width * height);
6811 6811
6812 rc = fn_TIFFReadRGBAImage (tiff, width, height, buf, 0); 6812 rc = fn_TIFFReadRGBAImage (tiff, width, height, buf, 0);
6813 6813
@@ -7036,8 +7036,8 @@ init_gif_functions (Lisp_Object libraries)
7036typedef struct 7036typedef struct
7037{ 7037{
7038 unsigned char *bytes; 7038 unsigned char *bytes;
7039 size_t len; 7039 ptrdiff_t len;
7040 int index; 7040 ptrdiff_t index;
7041} 7041}
7042gif_memory_source; 7042gif_memory_source;
7043 7043
@@ -7670,7 +7670,8 @@ imagemagick_load_image (struct frame *f, struct image *img,
7670 height = MagickGetImageHeight (image_wand); 7670 height = MagickGetImageHeight (image_wand);
7671 width = MagickGetImageWidth (image_wand); 7671 width = MagickGetImageWidth (image_wand);
7672 7672
7673 if (! check_image_size (f, width, height)) 7673 if (! (width <= INT_MAX && height <= INT_MAX
7674 && check_image_size (f, width, height)))
7674 { 7675 {
7675 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil); 7676 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
7676 goto imagemagick_error; 7677 goto imagemagick_error;
@@ -7874,7 +7875,7 @@ recognize as images, such as C. See `imagemagick-types-inhibit'. */)
7874 size_t numf = 0; 7875 size_t numf = 0;
7875 ExceptionInfo ex; 7876 ExceptionInfo ex;
7876 char **imtypes = GetMagickList ("*", &numf, &ex); 7877 char **imtypes = GetMagickList ("*", &numf, &ex);
7877 int i; 7878 size_t i;
7878 Lisp_Object Qimagemagicktype; 7879 Lisp_Object Qimagemagicktype;
7879 for (i = 0; i < numf; i++) 7880 for (i = 0; i < numf; i++)
7880 { 7881 {