aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2011-07-16 17:34:43 -0700
committerPaul Eggert2011-07-16 17:34:43 -0700
commit134643946085b24a695d73b3d8f7af5aa23602aa (patch)
treedb15254a5f9e9f173e4c379dfb27d9a38431b677 /src
parent39e378da07fe365c6442dc95b937539eb31fe8ef (diff)
downloademacs-134643946085b24a695d73b3d8f7af5aa23602aa.tar.gz
emacs-134643946085b24a695d73b3d8f7af5aa23602aa.zip
Overflow, signedness and related fixes for images.
* dispextern.h (struct it.stack[0].u.image.image_id) (struct_it.image_id, struct image.id, struct image_cache.size) (struct image_cache.used, struct image_cache.ref_count): * gtkutil.c (update_frame_tool_bar): * image.c (x_reference_bitmap, Fimage_size, Fimage_mask_p) (Fimage_metadata, free_image_cache, clear_image_cache, lookup_image) (cache_image, mark_image_cache, x_kill_gs_process, Flookup_image): * nsmenu.m (update_frame_tool_bar): * xdisp.c (calc_pixel_width_or_height): * xfns.c (image_cache_refcount): Image IDs are now ptrdiff_t, not int, to avoid arbitrary limits on typical 64-bit hosts. * image.c (RANGED_INTEGERP, TYPE_RANGED_INTEGERP): New macros. (x_bitmap_pixmap, x_create_x_image_and_pixmap): Omit unnecessary casts to int. (parse_image_spec): Check that integers fall into 'int' range when the callers expect that. (image_ascent): Redo ascent calculation to avoid int overflow. (clear_image_cache): Avoid overflow when sqrt (INT_MAX) < nimages. (lookup_image): Remove unnecessary tests. (xbm_image_p): Locals are now of int, not EMACS_INT, since parse_image_check makes sure they fit into int. (png_load, gif_load, svg_load_image): Prefer int to unsigned where either will do. (tiff_handler): New function, combining the cores of the old tiff_error_handler and tiff_warning_handler. This function is rewritten to use vsnprintf and thereby avoid stack buffer overflows. It uses only the features of vsnprintf that are common to both POSIX and native Microsoft. (tiff_error_handler, tiff_warning_handler): Use it. (tiff_load, gif_load, imagemagick_load_image): Don't assume :index value fits in 'int'. (gif_load): Omit unnecessary cast to double, and avoid double-rounding. (imagemagick_load_image): Check that crop parameters fit into the integer types that MagickCropImage accepts. Don't assume Vimagemagick_render_type has a nonnegative value. Don't assume size_t fits in 'long'. (gs_load): Use printmax_t to print the widest integers possible. Check for integer overflow when computing image height and width.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog45
-rw-r--r--src/dispextern.h16
-rw-r--r--src/gtkutil.c2
-rw-r--r--src/image.c184
-rw-r--r--src/nsmenu.m2
-rw-r--r--src/xdisp.c2
-rw-r--r--src/xfns.c3
7 files changed, 160 insertions, 94 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index c19786fb72c..680e67e05f7 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,48 @@
12011-07-16 Paul Eggert <eggert@cs.ucla.edu>
2
3 Overflow, signedness and related fixes for images.
4
5 * dispextern.h (struct it.stack[0].u.image.image_id)
6 (struct_it.image_id, struct image.id, struct image_cache.size)
7 (struct image_cache.used, struct image_cache.ref_count):
8 * gtkutil.c (update_frame_tool_bar):
9 * image.c (x_reference_bitmap, Fimage_size, Fimage_mask_p)
10 (Fimage_metadata, free_image_cache, clear_image_cache, lookup_image)
11 (cache_image, mark_image_cache, x_kill_gs_process, Flookup_image):
12 * nsmenu.m (update_frame_tool_bar):
13 * xdisp.c (calc_pixel_width_or_height):
14 * xfns.c (image_cache_refcount):
15 Image IDs are now ptrdiff_t, not int, to avoid arbitrary limits
16 on typical 64-bit hosts.
17
18 * image.c (RANGED_INTEGERP, TYPE_RANGED_INTEGERP): New macros.
19 (x_bitmap_pixmap, x_create_x_image_and_pixmap):
20 Omit unnecessary casts to int.
21 (parse_image_spec): Check that integers fall into 'int' range
22 when the callers expect that.
23 (image_ascent): Redo ascent calculation to avoid int overflow.
24 (clear_image_cache): Avoid overflow when sqrt (INT_MAX) < nimages.
25 (lookup_image): Remove unnecessary tests.
26 (xbm_image_p): Locals are now of int, not EMACS_INT,
27 since parse_image_check makes sure they fit into int.
28 (png_load, gif_load, svg_load_image):
29 Prefer int to unsigned where either will do.
30 (tiff_handler): New function, combining the cores of the
31 old tiff_error_handler and tiff_warning_handler. This
32 function is rewritten to use vsnprintf and thereby avoid
33 stack buffer overflows. It uses only the features of vsnprintf
34 that are common to both POSIX and native Microsoft.
35 (tiff_error_handler, tiff_warning_handler): Use it.
36 (tiff_load, gif_load, imagemagick_load_image):
37 Don't assume :index value fits in 'int'.
38 (gif_load): Omit unnecessary cast to double, and avoid double-rounding.
39 (imagemagick_load_image): Check that crop parameters fit into
40 the integer types that MagickCropImage accepts. Don't assume
41 Vimagemagick_render_type has a nonnegative value. Don't assume
42 size_t fits in 'long'.
43 (gs_load): Use printmax_t to print the widest integers possible.
44 Check for integer overflow when computing image height and width.
45
12011-07-14 Paul Eggert <eggert@cs.ucla.edu> 462011-07-14 Paul Eggert <eggert@cs.ucla.edu>
2 47
3 Integer signedness and overflow and related fixes. (Bug#9079) 48 Integer signedness and overflow and related fixes. (Bug#9079)
diff --git a/src/dispextern.h b/src/dispextern.h
index dc44c698164..bb4da7d52a8 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -2246,7 +2246,7 @@ struct it
2246 struct { 2246 struct {
2247 Lisp_Object object; 2247 Lisp_Object object;
2248 struct it_slice slice; 2248 struct it_slice slice;
2249 int image_id; 2249 ptrdiff_t image_id;
2250 } image; 2250 } image;
2251 /* method == GET_FROM_COMPOSITION */ 2251 /* method == GET_FROM_COMPOSITION */
2252 struct { 2252 struct {
@@ -2376,7 +2376,7 @@ struct it
2376 enum glyphless_display_method glyphless_method; 2376 enum glyphless_display_method glyphless_method;
2377 2377
2378 /* If what == IT_IMAGE, the id of the image to display. */ 2378 /* If what == IT_IMAGE, the id of the image to display. */
2379 int image_id; 2379 ptrdiff_t image_id;
2380 2380
2381 /* Values from `slice' property. */ 2381 /* Values from `slice' property. */
2382 struct it_slice slice; 2382 struct it_slice slice;
@@ -2826,7 +2826,7 @@ struct image
2826 EMACS_UINT hash; 2826 EMACS_UINT hash;
2827 2827
2828 /* Image id of this image. */ 2828 /* Image id of this image. */
2829 int id; 2829 ptrdiff_t id;
2830 2830
2831 /* Hash collision chain. */ 2831 /* Hash collision chain. */
2832 struct image *next, *prev; 2832 struct image *next, *prev;
@@ -2845,13 +2845,13 @@ struct image_cache
2845 struct image **images; 2845 struct image **images;
2846 2846
2847 /* Allocated size of `images'. */ 2847 /* Allocated size of `images'. */
2848 unsigned size; 2848 ptrdiff_t size;
2849 2849
2850 /* Number of images in the cache. */ 2850 /* Number of images in the cache. */
2851 unsigned used; 2851 ptrdiff_t used;
2852 2852
2853 /* Reference count (number of frames sharing this cache). */ 2853 /* Reference count (number of frames sharing this cache). */
2854 int refcount; 2854 ptrdiff_t refcount;
2855}; 2855};
2856 2856
2857 2857
@@ -3117,7 +3117,7 @@ void w32_reset_fringes (void);
3117extern int x_bitmap_height (struct frame *, ptrdiff_t); 3117extern int x_bitmap_height (struct frame *, ptrdiff_t);
3118extern int x_bitmap_width (struct frame *, ptrdiff_t); 3118extern int x_bitmap_width (struct frame *, ptrdiff_t);
3119extern int x_bitmap_pixmap (struct frame *, ptrdiff_t); 3119extern int x_bitmap_pixmap (struct frame *, ptrdiff_t);
3120extern void x_reference_bitmap (struct frame *, int); 3120extern void x_reference_bitmap (struct frame *, ptrdiff_t);
3121extern ptrdiff_t x_create_bitmap_from_data (struct frame *, char *, 3121extern ptrdiff_t x_create_bitmap_from_data (struct frame *, char *,
3122 unsigned int, unsigned int); 3122 unsigned int, unsigned int);
3123extern ptrdiff_t x_create_bitmap_from_file (struct frame *, Lisp_Object); 3123extern ptrdiff_t x_create_bitmap_from_file (struct frame *, Lisp_Object);
@@ -3138,7 +3138,7 @@ void clear_image_caches (Lisp_Object);
3138void mark_image_cache (struct image_cache *); 3138void mark_image_cache (struct image_cache *);
3139int valid_image_p (Lisp_Object); 3139int valid_image_p (Lisp_Object);
3140void prepare_image_for_display (struct frame *, struct image *); 3140void prepare_image_for_display (struct frame *, struct image *);
3141int lookup_image (struct frame *, Lisp_Object); 3141ptrdiff_t lookup_image (struct frame *, Lisp_Object);
3142 3142
3143unsigned long image_background (struct image *, struct frame *, 3143unsigned long image_background (struct image *, struct frame *,
3144 XImagePtr_or_DC ximg); 3144 XImagePtr_or_DC ximg);
diff --git a/src/gtkutil.c b/src/gtkutil.c
index 8826b08851a..70bc18a75ff 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -4429,7 +4429,7 @@ update_frame_tool_bar (FRAME_PTR f)
4429 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P)); 4429 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
4430 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P)); 4430 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
4431 int idx; 4431 int idx;
4432 int img_id; 4432 ptrdiff_t img_id;
4433 int icon_size = 0; 4433 int icon_size = 0;
4434 struct image *img = NULL; 4434 struct image *img = NULL;
4435 Lisp_Object image; 4435 Lisp_Object image;
diff --git a/src/image.c b/src/image.c
index 7a5ac40b3d2..3a58be5d85e 100644
--- a/src/image.c
+++ b/src/image.c
@@ -48,6 +48,11 @@ 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
51#ifdef HAVE_X_WINDOWS 56#ifdef HAVE_X_WINDOWS
52#include "xterm.h" 57#include "xterm.h"
53#include <sys/types.h> 58#include <sys/types.h>
@@ -196,7 +201,7 @@ x_bitmap_width (FRAME_PTR f, ptrdiff_t id)
196int 201int
197x_bitmap_pixmap (FRAME_PTR f, ptrdiff_t id) 202x_bitmap_pixmap (FRAME_PTR f, ptrdiff_t id)
198{ 203{
199 return (int) FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].pixmap; 204 return FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].pixmap;
200} 205}
201#endif 206#endif
202 207
@@ -245,7 +250,7 @@ x_allocate_bitmap_record (FRAME_PTR f)
245/* Add one reference to the reference count of the bitmap with id ID. */ 250/* Add one reference to the reference count of the bitmap with id ID. */
246 251
247void 252void
248x_reference_bitmap (FRAME_PTR f, int id) 253x_reference_bitmap (FRAME_PTR f, ptrdiff_t id)
249{ 254{
250 ++FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].refcount; 255 ++FRAME_X_DISPLAY_INFO (f)->bitmaps[id - 1].refcount;
251} 256}
@@ -807,29 +812,30 @@ parse_image_spec (Lisp_Object spec, struct image_keyword *keywords,
807 break; 812 break;
808 813
809 case IMAGE_POSITIVE_INTEGER_VALUE: 814 case IMAGE_POSITIVE_INTEGER_VALUE:
810 if (!INTEGERP (value) || XINT (value) <= 0) 815 if (! RANGED_INTEGERP (1, value, INT_MAX))
811 return 0; 816 return 0;
812 break; 817 break;
813 818
814 case IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR: 819 case IMAGE_POSITIVE_INTEGER_VALUE_OR_PAIR:
815 if (INTEGERP (value) && XINT (value) >= 0) 820 if (RANGED_INTEGERP (1, value, INT_MAX))
816 break; 821 break;
817 if (CONSP (value) 822 if (CONSP (value)
818 && INTEGERP (XCAR (value)) && INTEGERP (XCDR (value)) 823 && RANGED_INTEGERP (1, XCAR (value), INT_MAX)
819 && XINT (XCAR (value)) >= 0 && XINT (XCDR (value)) >= 0) 824 && RANGED_INTEGERP (1, XCDR (value), INT_MAX))
820 break; 825 break;
821 return 0; 826 return 0;
822 827
823 case IMAGE_ASCENT_VALUE: 828 case IMAGE_ASCENT_VALUE:
824 if (SYMBOLP (value) && EQ (value, Qcenter)) 829 if (SYMBOLP (value) && EQ (value, Qcenter))
825 break; 830 break;
826 else if (INTEGERP (value) 831 else if (RANGED_INTEGERP (0, value, 100))
827 && XINT (value) >= 0
828 && XINT (value) <= 100)
829 break; 832 break;
830 return 0; 833 return 0;
831 834
832 case IMAGE_NON_NEGATIVE_INTEGER_VALUE: 835 case IMAGE_NON_NEGATIVE_INTEGER_VALUE:
836 /* Unlike the other integer-related cases, this one does not
837 verify that VALUE fits in 'int'. This is because callers
838 want EMACS_INT. */
833 if (!INTEGERP (value) || XINT (value) < 0) 839 if (!INTEGERP (value) || XINT (value) < 0)
834 return 0; 840 return 0;
835 break; 841 break;
@@ -849,7 +855,7 @@ parse_image_spec (Lisp_Object spec, struct image_keyword *keywords,
849 break; 855 break;
850 856
851 case IMAGE_INTEGER_VALUE: 857 case IMAGE_INTEGER_VALUE:
852 if (!INTEGERP (value)) 858 if (! TYPE_RANGED_INTEGERP (int, value))
853 return 0; 859 return 0;
854 break; 860 break;
855 861
@@ -919,7 +925,7 @@ or omitted means use the selected frame. */)
919 if (valid_image_p (spec)) 925 if (valid_image_p (spec))
920 { 926 {
921 struct frame *f = check_x_frame (frame); 927 struct frame *f = check_x_frame (frame);
922 int id = lookup_image (f, spec); 928 ptrdiff_t id = lookup_image (f, spec);
923 struct image *img = IMAGE_FROM_ID (f, id); 929 struct image *img = IMAGE_FROM_ID (f, id);
924 int width = img->width + 2 * img->hmargin; 930 int width = img->width + 2 * img->hmargin;
925 int height = img->height + 2 * img->vmargin; 931 int height = img->height + 2 * img->vmargin;
@@ -949,7 +955,7 @@ or omitted means use the selected frame. */)
949 if (valid_image_p (spec)) 955 if (valid_image_p (spec))
950 { 956 {
951 struct frame *f = check_x_frame (frame); 957 struct frame *f = check_x_frame (frame);
952 int id = lookup_image (f, spec); 958 ptrdiff_t id = lookup_image (f, spec);
953 struct image *img = IMAGE_FROM_ID (f, id); 959 struct image *img = IMAGE_FROM_ID (f, id);
954 if (img->mask) 960 if (img->mask)
955 mask = Qt; 961 mask = Qt;
@@ -972,7 +978,7 @@ or omitted means use the selected frame. */)
972 if (valid_image_p (spec)) 978 if (valid_image_p (spec))
973 { 979 {
974 struct frame *f = check_x_frame (frame); 980 struct frame *f = check_x_frame (frame);
975 int id = lookup_image (f, spec); 981 ptrdiff_t id = lookup_image (f, spec);
976 struct image *img = IMAGE_FROM_ID (f, id); 982 struct image *img = IMAGE_FROM_ID (f, id);
977 ext = img->lisp_data; 983 ext = img->lisp_data;
978 } 984 }
@@ -1121,7 +1127,7 @@ image_ascent (struct image *img, struct face *face, struct glyph_slice *slice)
1121 ascent = height / 2; 1127 ascent = height / 2;
1122 } 1128 }
1123 else 1129 else
1124 ascent = (int) (height * img->ascent / 100.0); 1130 ascent = height * (img->ascent / 100.0);
1125 1131
1126 return ascent; 1132 return ascent;
1127} 1133}
@@ -1466,7 +1472,7 @@ free_image_cache (struct frame *f)
1466 struct image_cache *c = FRAME_IMAGE_CACHE (f); 1472 struct image_cache *c = FRAME_IMAGE_CACHE (f);
1467 if (c) 1473 if (c)
1468 { 1474 {
1469 int i; 1475 ptrdiff_t i;
1470 1476
1471 /* Cache should not be referenced by any frame when freed. */ 1477 /* Cache should not be referenced by any frame when freed. */
1472 xassert (c->refcount == 0); 1478 xassert (c->refcount == 0);
@@ -1496,7 +1502,7 @@ clear_image_cache (struct frame *f, Lisp_Object filter)
1496 1502
1497 if (c) 1503 if (c)
1498 { 1504 {
1499 int i, nfreed = 0; 1505 ptrdiff_t i, nfreed = 0;
1500 1506
1501 /* Block input so that we won't be interrupted by a SIGIO 1507 /* Block input so that we won't be interrupted by a SIGIO
1502 while being in an inconsistent state. */ 1508 while being in an inconsistent state. */
@@ -1520,8 +1526,8 @@ clear_image_cache (struct frame *f, Lisp_Object filter)
1520 { 1526 {
1521 /* Free cache based on timestamp. */ 1527 /* Free cache based on timestamp. */
1522 EMACS_TIME t; 1528 EMACS_TIME t;
1523 time_t old; 1529 double old, delay;
1524 int delay, nimages = 0; 1530 ptrdiff_t nimages = 0;
1525 1531
1526 for (i = 0; i < c->used; ++i) 1532 for (i = 0; i < c->used; ++i)
1527 if (c->images[i]) 1533 if (c->images[i])
@@ -1529,9 +1535,10 @@ clear_image_cache (struct frame *f, Lisp_Object filter)
1529 1535
1530 /* If the number of cached images has grown unusually large, 1536 /* If the number of cached images has grown unusually large,
1531 decrease the cache eviction delay (Bug#6230). */ 1537 decrease the cache eviction delay (Bug#6230). */
1532 delay = XFASTINT (Vimage_cache_eviction_delay); 1538 delay = XINT (Vimage_cache_eviction_delay);
1533 if (nimages > 40) 1539 if (nimages > 40)
1534 delay = max (1, 1600 * delay / (nimages*nimages)); 1540 delay = 1600 * delay / nimages / nimages;
1541 delay = max (delay, 1);
1535 1542
1536 EMACS_GET_TIME (t); 1543 EMACS_GET_TIME (t);
1537 old = EMACS_SECS (t) - delay; 1544 old = EMACS_SECS (t) - delay;
@@ -1707,7 +1714,7 @@ postprocess_image (struct frame *f, struct image *img)
1707/* Return the id of image with Lisp specification SPEC on frame F. 1714/* Return the id of image with Lisp specification SPEC on frame F.
1708 SPEC must be a valid Lisp image specification (see valid_image_p). */ 1715 SPEC must be a valid Lisp image specification (see valid_image_p). */
1709 1716
1710int 1717ptrdiff_t
1711lookup_image (struct frame *f, Lisp_Object spec) 1718lookup_image (struct frame *f, Lisp_Object spec)
1712{ 1719{
1713 struct image *img; 1720 struct image *img;
@@ -1766,15 +1773,12 @@ lookup_image (struct frame *f, Lisp_Object spec)
1766 img->ascent = CENTERED_IMAGE_ASCENT; 1773 img->ascent = CENTERED_IMAGE_ASCENT;
1767 1774
1768 margin = image_spec_value (spec, QCmargin, NULL); 1775 margin = image_spec_value (spec, QCmargin, NULL);
1769 if (INTEGERP (margin) && XINT (margin) >= 0) 1776 if (INTEGERP (margin))
1770 img->vmargin = img->hmargin = XFASTINT (margin); 1777 img->vmargin = img->hmargin = XFASTINT (margin);
1771 else if (CONSP (margin) && INTEGERP (XCAR (margin)) 1778 else if (CONSP (margin))
1772 && INTEGERP (XCDR (margin)))
1773 { 1779 {
1774 if (XINT (XCAR (margin)) > 0) 1780 img->hmargin = XFASTINT (XCAR (margin));
1775 img->hmargin = XFASTINT (XCAR (margin)); 1781 img->vmargin = XFASTINT (XCDR (margin));
1776 if (XINT (XCDR (margin)) > 0)
1777 img->vmargin = XFASTINT (XCDR (margin));
1778 } 1782 }
1779 1783
1780 relief = image_spec_value (spec, QCrelief, NULL); 1784 relief = image_spec_value (spec, QCrelief, NULL);
@@ -1821,7 +1825,7 @@ static void
1821cache_image (struct frame *f, struct image *img) 1825cache_image (struct frame *f, struct image *img)
1822{ 1826{
1823 struct image_cache *c = FRAME_IMAGE_CACHE (f); 1827 struct image_cache *c = FRAME_IMAGE_CACHE (f);
1824 int i; 1828 ptrdiff_t i;
1825 1829
1826 /* Find a free slot in c->images. */ 1830 /* Find a free slot in c->images. */
1827 for (i = 0; i < c->used; ++i) 1831 for (i = 0; i < c->used; ++i)
@@ -1875,7 +1879,7 @@ mark_image_cache (struct image_cache *c)
1875{ 1879{
1876 if (c) 1880 if (c)
1877 { 1881 {
1878 int i; 1882 ptrdiff_t i;
1879 for (i = 0; i < c->used; ++i) 1883 for (i = 0; i < c->used; ++i)
1880 if (c->images[i]) 1884 if (c->images[i])
1881 mark_image (c->images[i]); 1885 mark_image (c->images[i]);
@@ -2066,7 +2070,7 @@ x_create_x_image_and_pixmap (struct frame *f, int width, int height, int depth,
2066 DWORD err = GetLastError (); 2070 DWORD err = GetLastError ();
2067 Lisp_Object errcode; 2071 Lisp_Object errcode;
2068 /* All system errors are < 10000, so the following is safe. */ 2072 /* All system errors are < 10000, so the following is safe. */
2069 XSETINT (errcode, (int) err); 2073 XSETINT (errcode, err);
2070 image_error ("Unable to create bitmap, error code %d", errcode, Qnil); 2074 image_error ("Unable to create bitmap, error code %d", errcode, Qnil);
2071 x_destroy_x_image (*ximg); 2075 x_destroy_x_image (*ximg);
2072 return 0; 2076 return 0;
@@ -2345,7 +2349,7 @@ xbm_image_p (Lisp_Object object)
2345 else 2349 else
2346 { 2350 {
2347 Lisp_Object data; 2351 Lisp_Object data;
2348 EMACS_INT width, height; 2352 int width, height;
2349 2353
2350 /* Entries for `:width', `:height' and `:data' must be present. */ 2354 /* Entries for `:width', `:height' and `:data' must be present. */
2351 if (!kw[XBM_WIDTH].count 2355 if (!kw[XBM_WIDTH].count
@@ -5870,7 +5874,7 @@ png_load (struct frame *f, struct image *img)
5870 5874
5871 for (x = 0; x < width; ++x) 5875 for (x = 0; x < width; ++x)
5872 { 5876 {
5873 unsigned r, g, b; 5877 int r, g, b;
5874 5878
5875 r = *p++ << 8; 5879 r = *p++ << 8;
5876 g = *p++ << 8; 5880 g = *p++ << 8;
@@ -6735,17 +6739,29 @@ tiff_size_of_memory (thandle_t data)
6735} 6739}
6736 6740
6737 6741
6742static void tiff_handler (const char *, const char *, const char *, va_list)
6743 ATTRIBUTE_FORMAT_PRINTF (3, 0);
6744static void
6745tiff_handler (const char *log_format, const char *title,
6746 const char *format, va_list ap)
6747{
6748 /* doprnt is not suitable here, as TIFF handlers are called from
6749 libtiff and are passed arbitrary printf directives. Instead, use
6750 vsnprintf, taking care to be portable to nonstandard environments
6751 where vsnprintf returns -1 on buffer overflow. Since it's just a
6752 log entry, it's OK to truncate it. */
6753 char buf[4000];
6754 int len = vsnprintf (buf, sizeof buf, format, ap);
6755 add_to_log (log_format, build_string (title),
6756 make_string (buf, max (0, min (len, sizeof buf - 1))));
6757}
6758
6738static void tiff_error_handler (const char *, const char *, va_list) 6759static void tiff_error_handler (const char *, const char *, va_list)
6739 ATTRIBUTE_FORMAT_PRINTF (2, 0); 6760 ATTRIBUTE_FORMAT_PRINTF (2, 0);
6740static void 6761static void
6741tiff_error_handler (const char *title, const char *format, va_list ap) 6762tiff_error_handler (const char *title, const char *format, va_list ap)
6742{ 6763{
6743 char buf[512]; 6764 tiff_handler ("TIFF error: %s %s", title, format, ap);
6744 int len;
6745
6746 len = sprintf (buf, "TIFF error: %s ", title);
6747 vsprintf (buf + len, format, ap);
6748 add_to_log (buf, Qnil, Qnil);
6749} 6765}
6750 6766
6751 6767
@@ -6754,12 +6770,7 @@ static void tiff_warning_handler (const char *, const char *, va_list)
6754static void 6770static void
6755tiff_warning_handler (const char *title, const char *format, va_list ap) 6771tiff_warning_handler (const char *title, const char *format, va_list ap)
6756{ 6772{
6757 char buf[512]; 6773 tiff_handler ("TIFF warning: %s %s", title, format, ap);
6758 int len;
6759
6760 len = sprintf (buf, "TIFF warning: %s ", title);
6761 vsprintf (buf + len, format, ap);
6762 add_to_log (buf, Qnil, Qnil);
6763} 6774}
6764 6775
6765 6776
@@ -6835,8 +6846,9 @@ tiff_load (struct frame *f, struct image *img)
6835 image = image_spec_value (img->spec, QCindex, NULL); 6846 image = image_spec_value (img->spec, QCindex, NULL);
6836 if (INTEGERP (image)) 6847 if (INTEGERP (image))
6837 { 6848 {
6838 int ino = XFASTINT (image); 6849 EMACS_INT ino = XFASTINT (image);
6839 if (!fn_TIFFSetDirectory (tiff, ino)) 6850 if (! (TYPE_MINIMUM (tdir_t) <= ino && ino <= TYPE_MAXIMUM (tdir_t)
6851 && fn_TIFFSetDirectory (tiff, ino)))
6840 { 6852 {
6841 image_error ("Invalid image number `%s' in image `%s'", 6853 image_error ("Invalid image number `%s' in image `%s'",
6842 image, img->spec); 6854 image, img->spec);
@@ -7135,7 +7147,7 @@ gif_load (struct frame *f, struct image *img)
7135 Lisp_Object specified_file = image_spec_value (img->spec, QCfile, NULL); 7147 Lisp_Object specified_file = image_spec_value (img->spec, QCfile, NULL);
7136 Lisp_Object specified_data = image_spec_value (img->spec, QCdata, NULL); 7148 Lisp_Object specified_data = image_spec_value (img->spec, QCdata, NULL);
7137 unsigned long bgcolor = 0; 7149 unsigned long bgcolor = 0;
7138 int idx; 7150 EMACS_INT idx;
7139 7151
7140 if (NILP (specified_data)) 7152 if (NILP (specified_data))
7141 { 7153 {
@@ -7365,7 +7377,7 @@ gif_load (struct frame *f, struct image *img)
7365 img->lisp_data = Qnil; 7377 img->lisp_data = Qnil;
7366 if (gif->SavedImages[idx].ExtensionBlockCount > 0) 7378 if (gif->SavedImages[idx].ExtensionBlockCount > 0)
7367 { 7379 {
7368 unsigned int delay = 0; 7380 int delay = 0;
7369 ExtensionBlock *ext = gif->SavedImages[idx].ExtensionBlocks; 7381 ExtensionBlock *ext = gif->SavedImages[idx].ExtensionBlocks;
7370 for (i = 0; i < gif->SavedImages[idx].ExtensionBlockCount; i++, ext++) 7382 for (i = 0; i < gif->SavedImages[idx].ExtensionBlockCount; i++, ext++)
7371 /* Append (... FUNCTION "BYTES") */ 7383 /* Append (... FUNCTION "BYTES") */
@@ -7386,7 +7398,7 @@ gif_load (struct frame *f, struct image *img)
7386 if (delay) 7398 if (delay)
7387 img->lisp_data 7399 img->lisp_data
7388 = Fcons (Qdelay, 7400 = Fcons (Qdelay,
7389 Fcons (make_float (((double) delay) * 0.01), 7401 Fcons (make_float (delay / 100.0),
7390 img->lisp_data)); 7402 img->lisp_data));
7391 } 7403 }
7392 7404
@@ -7562,10 +7574,10 @@ imagemagick_load_image (struct frame *f, struct image *img,
7562 Lisp_Object image; 7574 Lisp_Object image;
7563 Lisp_Object value; 7575 Lisp_Object value;
7564 Lisp_Object crop; 7576 Lisp_Object crop;
7565 long ino; 7577 EMACS_INT ino;
7566 int desired_width, desired_height; 7578 int desired_width, desired_height;
7567 double rotation; 7579 double rotation;
7568 int imagemagick_rendermethod; 7580 EMACS_INT imagemagick_rendermethod;
7569 int pixelwidth; 7581 int pixelwidth;
7570 ImageInfo *image_info; 7582 ImageInfo *image_info;
7571 ExceptionInfo *exception; 7583 ExceptionInfo *exception;
@@ -7592,7 +7604,7 @@ imagemagick_load_image (struct frame *f, struct image *img,
7592 status = MagickPingImageBlob (ping_wand, contents, size); 7604 status = MagickPingImageBlob (ping_wand, contents, size);
7593 } 7605 }
7594 7606
7595 if (ino >= MagickGetNumberImages (ping_wand)) 7607 if (! (0 <= ino && ino < MagickGetNumberImages (ping_wand)))
7596 { 7608 {
7597 image_error ("Invalid image number `%s' in image `%s'", 7609 image_error ("Invalid image number `%s' in image `%s'",
7598 image, img->spec); 7610 image, img->spec);
@@ -7667,28 +7679,28 @@ imagemagick_load_image (struct frame *f, struct image *img,
7667 efficient. */ 7679 efficient. */
7668 crop = image_spec_value (img->spec, QCcrop, NULL); 7680 crop = image_spec_value (img->spec, QCcrop, NULL);
7669 7681
7670 if (CONSP (crop) && INTEGERP (XCAR (crop))) 7682 if (CONSP (crop) && TYPE_RANGED_INTEGERP (size_t, XCAR (crop)))
7671 { 7683 {
7672 /* After some testing, it seems MagickCropImage is the fastest crop 7684 /* After some testing, it seems MagickCropImage is the fastest crop
7673 function in ImageMagick. This crop function seems to do less copying 7685 function in ImageMagick. This crop function seems to do less copying
7674 than the alternatives, but it still reads the entire image into memory 7686 than the alternatives, but it still reads the entire image into memory
7675 before croping, which is aparently difficult to avoid when using 7687 before cropping, which is apparently difficult to avoid when using
7676 imagemagick. */ 7688 imagemagick. */
7677 int w, h; 7689 size_t crop_width = XINT (XCAR (crop));
7678 w = XFASTINT (XCAR (crop));
7679 crop = XCDR (crop); 7690 crop = XCDR (crop);
7680 if (CONSP (crop) && INTEGERP (XCAR (crop))) 7691 if (CONSP (crop) && TYPE_RANGED_INTEGERP (size_t, XCAR (crop)))
7681 { 7692 {
7682 h = XFASTINT (XCAR (crop)); 7693 size_t crop_height = XINT (XCAR (crop));
7683 crop = XCDR (crop); 7694 crop = XCDR (crop);
7684 if (CONSP (crop) && INTEGERP (XCAR (crop))) 7695 if (CONSP (crop) && TYPE_RANGED_INTEGERP (ssize_t, XCAR (crop)))
7685 { 7696 {
7686 x = XFASTINT (XCAR (crop)); 7697 ssize_t crop_x = XINT (XCAR (crop));
7687 crop = XCDR (crop); 7698 crop = XCDR (crop);
7688 if (CONSP (crop) && INTEGERP (XCAR (crop))) 7699 if (CONSP (crop) && TYPE_RANGED_INTEGERP (ssize_t, XCAR (crop)))
7689 { 7700 {
7690 y = XFASTINT (XCAR (crop)); 7701 ssize_t crop_y = XINT (XCAR (crop));
7691 MagickCropImage (image_wand, w, h, x, y); 7702 MagickCropImage (image_wand, crop_width, crop_height,
7703 crop_x, crop_y);
7692 } 7704 }
7693 } 7705 }
7694 } 7706 }
@@ -7734,9 +7746,11 @@ imagemagick_load_image (struct frame *f, struct image *img,
7734 7746
7735 init_color_table (); 7747 init_color_table ();
7736 imagemagick_rendermethod = (INTEGERP (Vimagemagick_render_type) 7748 imagemagick_rendermethod = (INTEGERP (Vimagemagick_render_type)
7737 ? XFASTINT (Vimagemagick_render_type) : 0); 7749 ? XINT (Vimagemagick_render_type) : 0);
7738 if (imagemagick_rendermethod == 0) 7750 if (imagemagick_rendermethod == 0)
7739 { 7751 {
7752 size_t image_height;
7753
7740 /* Try to create a x pixmap to hold the imagemagick pixmap. */ 7754 /* Try to create a x pixmap to hold the imagemagick pixmap. */
7741 if (!x_create_x_image_and_pixmap (f, width, height, 0, 7755 if (!x_create_x_image_and_pixmap (f, width, height, 0,
7742 &ximg, &img->pixmap)) 7756 &ximg, &img->pixmap))
@@ -7765,7 +7779,8 @@ imagemagick_load_image (struct frame *f, struct image *img,
7765 goto imagemagick_error; 7779 goto imagemagick_error;
7766 } 7780 }
7767 7781
7768 for (y = 0; y < (long) MagickGetImageHeight (image_wand); y++) 7782 image_height = MagickGetImageHeight (image_wand);
7783 for (y = 0; y < image_height; y++)
7769 { 7784 {
7770 pixels = PixelGetNextIteratorRow (iterator, &width); 7785 pixels = PixelGetNextIteratorRow (iterator, &width);
7771 if (pixels == (PixelWand **) NULL) 7786 if (pixels == (PixelWand **) NULL)
@@ -8271,10 +8286,10 @@ svg_load_image (struct frame *f, /* Pointer to emacs frame structure. *
8271 { 8286 {
8272 for (x = 0; x < width; ++x) 8287 for (x = 0; x < width; ++x)
8273 { 8288 {
8274 unsigned red; 8289 int red;
8275 unsigned green; 8290 int green;
8276 unsigned blue; 8291 int blue;
8277 unsigned opacity; 8292 int opacity;
8278 8293
8279 red = *pixels++; 8294 red = *pixels++;
8280 green = *pixels++; 8295 green = *pixels++;
@@ -8455,7 +8470,8 @@ gs_image_p (Lisp_Object object)
8455static int 8470static int
8456gs_load (struct frame *f, struct image *img) 8471gs_load (struct frame *f, struct image *img)
8457{ 8472{
8458 char buffer[100]; 8473 uprintmax_t printnum1, printnum2;
8474 char buffer[sizeof " " + INT_STRLEN_BOUND (printmax_t)];
8459 Lisp_Object window_and_pixmap_id = Qnil, loader, pt_height, pt_width; 8475 Lisp_Object window_and_pixmap_id = Qnil, loader, pt_height, pt_width;
8460 Lisp_Object frame; 8476 Lisp_Object frame;
8461 double in_width, in_height; 8477 double in_width, in_height;
@@ -8467,16 +8483,19 @@ gs_load (struct frame *f, struct image *img)
8467 info. */ 8483 info. */
8468 pt_width = image_spec_value (img->spec, QCpt_width, NULL); 8484 pt_width = image_spec_value (img->spec, QCpt_width, NULL);
8469 in_width = INTEGERP (pt_width) ? XFASTINT (pt_width) / 72.0 : 0; 8485 in_width = INTEGERP (pt_width) ? XFASTINT (pt_width) / 72.0 : 0;
8470 img->width = in_width * FRAME_X_DISPLAY_INFO (f)->resx; 8486 in_width *= FRAME_X_DISPLAY_INFO (f)->resx;
8471 pt_height = image_spec_value (img->spec, QCpt_height, NULL); 8487 pt_height = image_spec_value (img->spec, QCpt_height, NULL);
8472 in_height = INTEGERP (pt_height) ? XFASTINT (pt_height) / 72.0 : 0; 8488 in_height = INTEGERP (pt_height) ? XFASTINT (pt_height) / 72.0 : 0;
8473 img->height = in_height * FRAME_X_DISPLAY_INFO (f)->resy; 8489 in_height *= FRAME_X_DISPLAY_INFO (f)->resy;
8474 8490
8475 if (!check_image_size (f, img->width, img->height)) 8491 if (! (in_width <= INT_MAX && in_height <= INT_MAX
8492 && check_image_size (f, in_width, in_height)))
8476 { 8493 {
8477 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil); 8494 image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
8478 return 0; 8495 return 0;
8479 } 8496 }
8497 img->width = in_width;
8498 img->height = in_height;
8480 8499
8481 /* Create the pixmap. */ 8500 /* Create the pixmap. */
8482 xassert (img->pixmap == NO_PIXMAP); 8501 xassert (img->pixmap == NO_PIXMAP);
@@ -8501,14 +8520,14 @@ gs_load (struct frame *f, struct image *img)
8501 if successful. We do not record_unwind_protect here because 8520 if successful. We do not record_unwind_protect here because
8502 other places in redisplay like calling window scroll functions 8521 other places in redisplay like calling window scroll functions
8503 don't either. Let the Lisp loader use `unwind-protect' instead. */ 8522 don't either. Let the Lisp loader use `unwind-protect' instead. */
8504 sprintf (buffer, "%lu %lu", 8523 printnum1 = FRAME_X_WINDOW (f);
8505 (unsigned long) FRAME_X_WINDOW (f), 8524 printnum2 = img->pixmap;
8506 (unsigned long) img->pixmap); 8525 sprintf (buffer, "%"pMu" %"pMu, printnum1, printnum2);
8507 window_and_pixmap_id = build_string (buffer); 8526 window_and_pixmap_id = build_string (buffer);
8508 8527
8509 sprintf (buffer, "%lu %lu", 8528 printnum1 = FRAME_FOREGROUND_PIXEL (f);
8510 FRAME_FOREGROUND_PIXEL (f), 8529 printnum2 = FRAME_BACKGROUND_PIXEL (f);
8511 FRAME_BACKGROUND_PIXEL (f)); 8530 sprintf (buffer, "%"pMu" %"pMu, printnum1, printnum2);
8512 pixel_colors = build_string (buffer); 8531 pixel_colors = build_string (buffer);
8513 8532
8514 XSETFRAME (frame, f); 8533 XSETFRAME (frame, f);
@@ -8533,7 +8552,8 @@ void
8533x_kill_gs_process (Pixmap pixmap, struct frame *f) 8552x_kill_gs_process (Pixmap pixmap, struct frame *f)
8534{ 8553{
8535 struct image_cache *c = FRAME_IMAGE_CACHE (f); 8554 struct image_cache *c = FRAME_IMAGE_CACHE (f);
8536 int class, i; 8555 int class;
8556 ptrdiff_t i;
8537 struct image *img; 8557 struct image *img;
8538 8558
8539 /* Find the image containing PIXMAP. */ 8559 /* Find the image containing PIXMAP. */
@@ -8637,7 +8657,7 @@ DEFUN ("imagep", Fimagep, Simagep, 1, 1, 0,
8637DEFUN ("lookup-image", Flookup_image, Slookup_image, 1, 1, 0, "") 8657DEFUN ("lookup-image", Flookup_image, Slookup_image, 1, 1, 0, "")
8638 (Lisp_Object spec) 8658 (Lisp_Object spec)
8639{ 8659{
8640 int id = -1; 8660 ptrdiff_t id = -1;
8641 8661
8642 if (valid_image_p (spec)) 8662 if (valid_image_p (spec))
8643 id = lookup_image (SELECTED_FRAME (), spec); 8663 id = lookup_image (SELECTED_FRAME (), spec);
diff --git a/src/nsmenu.m b/src/nsmenu.m
index 6a9ee7dd4f5..95e23ff6512 100644
--- a/src/nsmenu.m
+++ b/src/nsmenu.m
@@ -1014,7 +1014,7 @@ update_frame_tool_bar (FRAME_PTR f)
1014 BOOL enabled_p = !NILP (TOOLPROP (TOOL_BAR_ITEM_ENABLED_P)); 1014 BOOL enabled_p = !NILP (TOOLPROP (TOOL_BAR_ITEM_ENABLED_P));
1015 BOOL selected_p = !NILP (TOOLPROP (TOOL_BAR_ITEM_SELECTED_P)); 1015 BOOL selected_p = !NILP (TOOLPROP (TOOL_BAR_ITEM_SELECTED_P));
1016 int idx; 1016 int idx;
1017 int img_id; 1017 ptrdiff_t img_id;
1018 struct image *img; 1018 struct image *img;
1019 Lisp_Object image; 1019 Lisp_Object image;
1020 Lisp_Object helpObj; 1020 Lisp_Object helpObj;
diff --git a/src/xdisp.c b/src/xdisp.c
index 5285d945975..50f6f79c941 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -21119,7 +21119,7 @@ calc_pixel_width_or_height (double *res, struct it *it, Lisp_Object prop,
21119 if (FRAME_WINDOW_P (it->f) 21119 if (FRAME_WINDOW_P (it->f)
21120 && valid_image_p (prop)) 21120 && valid_image_p (prop))
21121 { 21121 {
21122 int id = lookup_image (it->f, prop); 21122 ptrdiff_t id = lookup_image (it->f, prop);
21123 struct image *img = IMAGE_FROM_ID (it->f, id); 21123 struct image *img = IMAGE_FROM_ID (it->f, id);
21124 21124
21125 return OK_PIXELS (width_p ? img->width : img->height); 21125 return OK_PIXELS (width_p ? img->width : img->height);
diff --git a/src/xfns.c b/src/xfns.c
index 0d1e4a1bb5e..623b7847c1e 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -145,7 +145,8 @@ static Lisp_Object Qcompound_text, Qcancel_timer;
145Lisp_Object Qfont_param; 145Lisp_Object Qfont_param;
146 146
147#if GLYPH_DEBUG 147#if GLYPH_DEBUG
148static int image_cache_refcount, dpyinfo_refcount; 148static ptrdiff_t image_cache_refcount;
149static int dpyinfo_refcount;
149#endif 150#endif
150 151
151#if defined (USE_GTK) && defined (HAVE_FREETYPE) 152#if defined (USE_GTK) && defined (HAVE_FREETYPE)