aboutsummaryrefslogtreecommitdiffstats
path: root/src/image.c
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/image.c
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/image.c')
-rw-r--r--src/image.c184
1 files changed, 102 insertions, 82 deletions
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);