diff options
| author | Paul Eggert | 2011-07-28 17:23:08 -0700 |
|---|---|---|
| committer | Paul Eggert | 2011-07-28 17:23:08 -0700 |
| commit | ddff315164d62859e0eb87e89de9f785b953a39a (patch) | |
| tree | 173477b3b60a79ac3a9c619a11ed80a8b6cd1894 /src | |
| parent | 0eb0f3187d46ec0efdfc1df38565c160c759ecb2 (diff) | |
| download | emacs-ddff315164d62859e0eb87e89de9f785b953a39a.tar.gz emacs-ddff315164d62859e0eb87e89de9f785b953a39a.zip | |
* image.c: Integer and memory overflow fixes.
(RANGED_INTEGERP, TYPE_RANGED_INTEGERP): Remove; these are duplicate
now that they've been promoted to lisp.h.
(x_allocate_bitmap_record, x_alloc_image_color)
(make_image_cache, cache_image, xpm_load):
Don't update size until alloc is done.
(xpm_load, lookup_rgb_color, lookup_pixel_color, x_to_xcolors)
(x_detect_edges):
Check for size calculation overflow.
(ct_colors_allocated_max): New constant.
(x_to_xcolors, x_detect_edges): Reorder multiplicands to avoid
overflow.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 15 | ||||
| -rw-r--r-- | src/image.c | 61 |
2 files changed, 56 insertions, 20 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index b984072c6eb..5683578fedb 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,18 @@ | |||
| 1 | 2011-07-29 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | * image.c: Integer and memory overflow fixes. | ||
| 4 | (RANGED_INTEGERP, TYPE_RANGED_INTEGERP): Remove; these are duplicate | ||
| 5 | now that they've been promoted to lisp.h. | ||
| 6 | (x_allocate_bitmap_record, x_alloc_image_color) | ||
| 7 | (make_image_cache, cache_image, xpm_load): | ||
| 8 | Don't update size until alloc is done. | ||
| 9 | (xpm_load, lookup_rgb_color, lookup_pixel_color, x_to_xcolors) | ||
| 10 | (x_detect_edges): | ||
| 11 | Check for size calculation overflow. | ||
| 12 | (ct_colors_allocated_max): New constant. | ||
| 13 | (x_to_xcolors, x_detect_edges): Reorder multiplicands to avoid | ||
| 14 | overflow. | ||
| 15 | |||
| 1 | 2011-07-28 Paul Eggert <eggert@cs.ucla.edu> | 16 | 2011-07-28 Paul Eggert <eggert@cs.ucla.edu> |
| 2 | 17 | ||
| 3 | * gtkutil.c: Integer overflow fixes. | 18 | * gtkutil.c: Integer overflow fixes. |
diff --git a/src/image.c b/src/image.c index 974c525c4e6..52fd945e32a 100644 --- a/src/image.c +++ b/src/image.c | |||
| @@ -48,11 +48,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 48 | #include "termhooks.h" | 48 | #include "termhooks.h" |
| 49 | #include "font.h" | 49 | #include "font.h" |
| 50 | 50 | ||
| 51 | #define RANGED_INTEGERP(lo, x, hi) \ | ||
| 52 | (INTEGERP (x) && (lo) <= XINT (x) && XINT (x) <= (hi)) | ||
| 53 | #define TYPE_RANGED_INTEGERP(type, x) \ | ||
| 54 | RANGED_INTEGERP (TYPE_MINIMUM (type), x, TYPE_MAXIMUM (type)) | ||
| 55 | |||
| 56 | #ifdef HAVE_X_WINDOWS | 51 | #ifdef HAVE_X_WINDOWS |
| 57 | #include "xterm.h" | 52 | #include "xterm.h" |
| 58 | #include <sys/types.h> | 53 | #include <sys/types.h> |
| @@ -223,9 +218,9 @@ x_allocate_bitmap_record (FRAME_PTR f) | |||
| 223 | 218 | ||
| 224 | if (dpyinfo->bitmaps == NULL) | 219 | if (dpyinfo->bitmaps == NULL) |
| 225 | { | 220 | { |
| 226 | dpyinfo->bitmaps_size = 10; | ||
| 227 | dpyinfo->bitmaps | 221 | dpyinfo->bitmaps |
| 228 | = (Bitmap_Record *) xmalloc (dpyinfo->bitmaps_size * sizeof (Bitmap_Record)); | 222 | = (Bitmap_Record *) xmalloc (10 * sizeof (Bitmap_Record)); |
| 223 | dpyinfo->bitmaps_size = 10; | ||
| 229 | dpyinfo->bitmaps_last = 1; | 224 | dpyinfo->bitmaps_last = 1; |
| 230 | return 1; | 225 | return 1; |
| 231 | } | 226 | } |
| @@ -240,10 +235,11 @@ x_allocate_bitmap_record (FRAME_PTR f) | |||
| 240 | if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (Bitmap_Record) / 2 | 235 | if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (Bitmap_Record) / 2 |
| 241 | < dpyinfo->bitmaps_size) | 236 | < dpyinfo->bitmaps_size) |
| 242 | memory_full (SIZE_MAX); | 237 | memory_full (SIZE_MAX); |
| 243 | dpyinfo->bitmaps_size *= 2; | ||
| 244 | dpyinfo->bitmaps | 238 | dpyinfo->bitmaps |
| 245 | = (Bitmap_Record *) xrealloc (dpyinfo->bitmaps, | 239 | = (Bitmap_Record *) xrealloc (dpyinfo->bitmaps, |
| 246 | dpyinfo->bitmaps_size * sizeof (Bitmap_Record)); | 240 | (dpyinfo->bitmaps_size |
| 241 | * (2 * sizeof (Bitmap_Record)))); | ||
| 242 | dpyinfo->bitmaps_size *= 2; | ||
| 247 | return ++dpyinfo->bitmaps_last; | 243 | return ++dpyinfo->bitmaps_last; |
| 248 | } | 244 | } |
| 249 | 245 | ||
| @@ -1373,11 +1369,12 @@ x_alloc_image_color (struct frame *f, struct image *img, Lisp_Object color_name, | |||
| 1373 | { | 1369 | { |
| 1374 | /* This isn't called frequently so we get away with simply | 1370 | /* This isn't called frequently so we get away with simply |
| 1375 | reallocating the color vector to the needed size, here. */ | 1371 | reallocating the color vector to the needed size, here. */ |
| 1376 | ++img->ncolors; | 1372 | ptrdiff_t ncolors = img->ncolors + 1; |
| 1377 | img->colors = | 1373 | img->colors = |
| 1378 | (unsigned long *) xrealloc (img->colors, | 1374 | (unsigned long *) xrealloc (img->colors, |
| 1379 | img->ncolors * sizeof *img->colors); | 1375 | ncolors * sizeof *img->colors); |
| 1380 | img->colors[img->ncolors - 1] = color.pixel; | 1376 | img->colors[ncolors - 1] = color.pixel; |
| 1377 | img->ncolors = ncolors; | ||
| 1381 | result = color.pixel; | 1378 | result = color.pixel; |
| 1382 | } | 1379 | } |
| 1383 | else | 1380 | else |
| @@ -1405,8 +1402,9 @@ make_image_cache (void) | |||
| 1405 | int size; | 1402 | int size; |
| 1406 | 1403 | ||
| 1407 | memset (c, 0, sizeof *c); | 1404 | memset (c, 0, sizeof *c); |
| 1408 | c->size = 50; | 1405 | size = 50; |
| 1409 | c->images = (struct image **) xmalloc (c->size * sizeof *c->images); | 1406 | c->images = (struct image **) xmalloc (size * sizeof *c->images); |
| 1407 | c->size = size; | ||
| 1410 | size = IMAGE_CACHE_BUCKETS_SIZE * sizeof *c->buckets; | 1408 | size = IMAGE_CACHE_BUCKETS_SIZE * sizeof *c->buckets; |
| 1411 | c->buckets = (struct image **) xmalloc (size); | 1409 | c->buckets = (struct image **) xmalloc (size); |
| 1412 | memset (c->buckets, 0, size); | 1410 | memset (c->buckets, 0, size); |
| @@ -1837,9 +1835,10 @@ cache_image (struct frame *f, struct image *img) | |||
| 1837 | { | 1835 | { |
| 1838 | if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *c->images / 2 < c->size) | 1836 | if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *c->images / 2 < c->size) |
| 1839 | memory_full (SIZE_MAX); | 1837 | memory_full (SIZE_MAX); |
| 1838 | c->images = | ||
| 1839 | (struct image **) xrealloc (c->images, | ||
| 1840 | c->size * (2 * sizeof *c->images)); | ||
| 1840 | c->size *= 2; | 1841 | c->size *= 2; |
| 1841 | c->images = (struct image **) xrealloc (c->images, | ||
| 1842 | c->size * sizeof *c->images); | ||
| 1843 | } | 1842 | } |
| 1844 | 1843 | ||
| 1845 | /* Add IMG to c->images, and assign IMG an id. */ | 1844 | /* Add IMG to c->images, and assign IMG an id. */ |
| @@ -3581,9 +3580,12 @@ xpm_load (struct frame *f, struct image *img) | |||
| 3581 | #endif /* HAVE_NTGUI */ | 3580 | #endif /* HAVE_NTGUI */ |
| 3582 | 3581 | ||
| 3583 | /* Remember allocated colors. */ | 3582 | /* Remember allocated colors. */ |
| 3584 | img->ncolors = attrs.nalloc_pixels; | 3583 | if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *img->colors |
| 3584 | < attrs.nalloc_pixels) | ||
| 3585 | memory_full (SIZE_MAX); | ||
| 3585 | img->colors = (unsigned long *) xmalloc (img->ncolors | 3586 | img->colors = (unsigned long *) xmalloc (img->ncolors |
| 3586 | * sizeof *img->colors); | 3587 | * sizeof *img->colors); |
| 3588 | img->ncolors = attrs.nalloc_pixels; | ||
| 3587 | for (i = 0; i < attrs.nalloc_pixels; ++i) | 3589 | for (i = 0; i < attrs.nalloc_pixels; ++i) |
| 3588 | { | 3590 | { |
| 3589 | img->colors[i] = attrs.alloc_pixels[i]; | 3591 | img->colors[i] = attrs.alloc_pixels[i]; |
| @@ -4157,6 +4159,12 @@ static struct ct_color **ct_table; | |||
| 4157 | /* Number of entries in the color table. */ | 4159 | /* Number of entries in the color table. */ |
| 4158 | 4160 | ||
| 4159 | static int ct_colors_allocated; | 4161 | static int ct_colors_allocated; |
| 4162 | enum | ||
| 4163 | { | ||
| 4164 | ct_colors_allocated_max = | ||
| 4165 | min (INT_MAX, | ||
| 4166 | min (PTRDIFF_MAX, SIZE_MAX) / sizeof (unsigned long)) | ||
| 4167 | }; | ||
| 4160 | 4168 | ||
| 4161 | /* Initialize the color table. */ | 4169 | /* Initialize the color table. */ |
| 4162 | 4170 | ||
| @@ -4243,7 +4251,14 @@ lookup_rgb_color (struct frame *f, int r, int g, int b) | |||
| 4243 | XColor color; | 4251 | XColor color; |
| 4244 | Colormap cmap; | 4252 | Colormap cmap; |
| 4245 | int rc; | 4253 | int rc; |
| 4254 | #else | ||
| 4255 | COLORREF color; | ||
| 4256 | #endif | ||
| 4246 | 4257 | ||
| 4258 | if (ct_colors_allocated_max <= ct_colors_allocated) | ||
| 4259 | return FRAME_FOREGROUND_PIXEL (f); | ||
| 4260 | |||
| 4261 | #ifdef HAVE_X_WINDOWS | ||
| 4247 | color.red = r; | 4262 | color.red = r; |
| 4248 | color.green = g; | 4263 | color.green = g; |
| 4249 | color.blue = b; | 4264 | color.blue = b; |
| @@ -4265,7 +4280,6 @@ lookup_rgb_color (struct frame *f, int r, int g, int b) | |||
| 4265 | return FRAME_FOREGROUND_PIXEL (f); | 4280 | return FRAME_FOREGROUND_PIXEL (f); |
| 4266 | 4281 | ||
| 4267 | #else | 4282 | #else |
| 4268 | COLORREF color; | ||
| 4269 | #ifdef HAVE_NTGUI | 4283 | #ifdef HAVE_NTGUI |
| 4270 | color = PALETTERGB (r, g, b); | 4284 | color = PALETTERGB (r, g, b); |
| 4271 | #else | 4285 | #else |
| @@ -4306,6 +4320,9 @@ lookup_pixel_color (struct frame *f, unsigned long pixel) | |||
| 4306 | Colormap cmap; | 4320 | Colormap cmap; |
| 4307 | int rc; | 4321 | int rc; |
| 4308 | 4322 | ||
| 4323 | if (ct_colors_allocated_max <= ct_colors_allocated) | ||
| 4324 | return FRAME_FOREGROUND_PIXEL (f); | ||
| 4325 | |||
| 4309 | #ifdef HAVE_X_WINDOWS | 4326 | #ifdef HAVE_X_WINDOWS |
| 4310 | cmap = FRAME_X_COLORMAP (f); | 4327 | cmap = FRAME_X_COLORMAP (f); |
| 4311 | color.pixel = pixel; | 4328 | color.pixel = pixel; |
| @@ -4444,7 +4461,9 @@ x_to_xcolors (struct frame *f, struct image *img, int rgb_p) | |||
| 4444 | HGDIOBJ prev; | 4461 | HGDIOBJ prev; |
| 4445 | #endif /* HAVE_NTGUI */ | 4462 | #endif /* HAVE_NTGUI */ |
| 4446 | 4463 | ||
| 4447 | colors = (XColor *) xmalloc (img->width * img->height * sizeof *colors); | 4464 | if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *colors / img->width < img->height) |
| 4465 | memory_full (SIZE_MAX); | ||
| 4466 | colors = (XColor *) xmalloc (sizeof *colors * img->width * img->height); | ||
| 4448 | 4467 | ||
| 4449 | #ifndef HAVE_NTGUI | 4468 | #ifndef HAVE_NTGUI |
| 4450 | /* Get the X image IMG->pixmap. */ | 4469 | /* Get the X image IMG->pixmap. */ |
| @@ -4596,7 +4615,9 @@ x_detect_edges (struct frame *f, struct image *img, int *matrix, int color_adjus | |||
| 4596 | 4615 | ||
| 4597 | #define COLOR(A, X, Y) ((A) + (Y) * img->width + (X)) | 4616 | #define COLOR(A, X, Y) ((A) + (Y) * img->width + (X)) |
| 4598 | 4617 | ||
| 4599 | new = (XColor *) xmalloc (img->width * img->height * sizeof *new); | 4618 | if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *new / img->width < img->height) |
| 4619 | memory_full (SIZE_MAX); | ||
| 4620 | new = (XColor *) xmalloc (sizeof *new * img->width * img->height); | ||
| 4600 | 4621 | ||
| 4601 | for (y = 0; y < img->height; ++y) | 4622 | for (y = 0; y < img->height; ++y) |
| 4602 | { | 4623 | { |