Subject: integer overflow etc. issues (e.g., image crashes Emacs)

From: Paul Eggert <[email-masked]>
Date: Thu, 14 Jul 2011 00:55:39 -0700

Package: emacs
Version: 24.0.50
Tags: patch

I examined more of the Emacs C source code, looking for problems with
integer overflow and signedness issues, and found several issues,
all fixed in the patch below.

This patch does not add any features to Emacs, and it focuses on
fixing bugs, so I hope that it's suitable for the trunk now.

Here's an example bug.  Take the attached file 46341x46341.png.gz,
uncompress it with 'gunzip', start up Emacs under X Windows, execute
(setq max-image-size 50000), and then visit the file 46341x46341.png.
If you're lucky Emacs will thrash around for quite some time and then
dump core.  If you're unlucky Emacs's internal data structures will be
silently corrupted.

To make things a bit easier on my hand examination (so that I didn't
have so many false matches for 'size_t') this patch assumes the
cleanups assuming C89 libraries that I circulated a week or two ago
<http://lists.gnu.org/archive/html/emacs-devel/2011-07/msg00261.html>
<http://lists.gnu.org/archive/html/emacs-devel/2011-07/msg00402.html>.

This bug report to some extent follows up on Bug#8873, but takes a
somewhat different tack, as it mostly focuses on unsigned integers.

# Bazaar merge directive format 2 (Bazaar 0.90)
# revision_id: [email-masked]
# target_branch: ../memcmp
# testament_sha1: 9592d4b269a0873b3fbe5e662fc3f163f4678863
# timestamp: 2011-07-14 00:51:13 -0700
# base_revision_id: [email-masked]
# 
# Begin patch
=== modified file 'src/ChangeLog'
--- src/ChangeLog	2011-07-14 07:31:04 +0000
+++ src/ChangeLog	2011-07-14 07:50:51 +0000
@@ -1,5 +1,176 @@
 2011-07-14  Paul Eggert  <[email-masked]>
 
+	Integer signedness and overflow and related fixes.
+
+	* image.c: Improve checking for integer overflow.
+	(check_image_size): Assume that f is nonnull, since
+	it is always nonnull in practice.  This is one less thing to
+	worry about when checking for integer overflow later.
+	(x_check_image_size): New function, which checks for integer
+	overflow issues inside X.
+	(x_create_x_image_and_pixmap, xbm_read_bitmap_data): Use it.
+	This removes the need for a memory_full check.
+	(xbm_image_p): Rewrite to avoid integer multiplication overflow.
+	(Create_Pixmap_From_Bitmap_Data, xbm_load): Use x_check_image_size.
+	(xbm_read_bitmap_data): Change locals back to 'int', since
+	their values must fit in 'int'.
+	(xpm_load_image, png_load, tiff_load):
+	Invoke x_create_x_image_and_pixmap earlier,
+	to avoid much needless work if the image is too large.
+	(tiff_load): Treat overly large images as if
+	x_create_x_image_and_pixmap failed, not as malloc failures.
+	(gs_load): Use x_check_image_size.
+
+	* gtkutil.c: Omit integer casts.
+	(xg_get_pixbuf_from_pixmap): Remove unnecessary cast.
+	(xg_set_toolkit_scroll_bar_thumb): Rewrite to avoid need for cast.
+
+	* image.c (png_load): Don't assume height * row_bytes fits in 'int'.
+
+	* bidi.c (bidi_dump_cached_states): Use pD to print ptrdiff_t.
+
+	* xfaces.c (Fbitmap_spec_p): Fix integer overflow bug.
+	Without this fix, (bitmap-spec-p '(34359738368 1 "x"))
+	would wrongly return t on a 64-bit host.
+
+	* dispnew.c (init_display): Use *_RANGE_OVERFLOW macros.
+	The plain *_OVERFLOW macros run afoul of GCC bug 49705
+	<http://gcc.gnu.org/bugzilla/show_bug.cgi?id=49705>
+	and therefore cause GCC to emit a bogus diagnostic in some cases.
+
+	* 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'.
+
+	Improve hashing quality when configured --with-wide-int.
+	* fns.c (hash_string): New function, taken from sxhash_string.
+	Do not discard information about ASCII character case; this
+	discarding is no longer needed.
+	(sxhash-string): Use it.  Change sig to match it.  Caller changed.
+	* lisp.h: Declare it.
+	* lread.c (hash_string): Remove, since we now use fns.c's version.
+	The fns.c version returns a wider integer if --with-wide-int is
+	specified, so this should help the quality of the hashing a bit.
+
+	* emacs.c: Integer overflow minor fix.
+	(heap_bss_diff): Now uprintmax_t, not unsigned long.  All used changed.
+	Define only if GNU_LINUX.
+	(main, Fdump_emacs): Set and use heap_bss_diff only if GNU_LINUX.
+
+	* dispnew.c: Integer signedness and overflow fixes.
+	Remove unnecessary forward decls, that were a maintenance hassle.
+	(history_tick): Now uprintmax_t, so it's more likely to avoid overflow.
+	All uses changed.
+	(adjust_glyph_matrix, realloc_glyph_pool, adjust_frame_message_buffer)
+	(scrolling_window): Use ptrdiff_t, not int, for byte count.
+	(prepare_desired_row, line_draw_cost):
+	Use int, not unsigned, where either works.
+	(save_current_matrix, restore_current_matrix):
+	Use ptrdiff_t, not size_t, where either works.
+	(init_display): Check for overflow more accurately, and without
+	relying on undefined behavior.
+
+	* editfns.c (pWIDE, pWIDElen, signed_wide, unsigned_wide):
+	Remove, replacing with the new symbols in lisp.h.  All uses changed.
+	* fileio.c (make_temp_name):
+	* filelock.c (lock_file_1, lock_file):
+	* xdisp.c (message_dolog):
+	Don't assume PRIdMAX etc. works; this isn't portable to pre-C99 hosts.
+	Use pMd etc. instead.
+	* lisp.h (printmax_t, uprintmax_t, pMd, pMu): New types and macros,
+	replacing the pWIDE etc. symbols removed from editfns.c.
+
+	* keyboard.h (num_input_events): Now uintmax_t.
+	This is (very slightly) less likely to mess up due to wraparound.
+	All uses changed.
+
+	* buffer.c: Integer signedness fixes.
+	(alloc_buffer_text, enlarge_buffer_text):
+	Use ptrdiff_t rather than size_t when either will do, as we prefer
+	signed integers.
+
+	* bidi.c: Integer signedness and overflow fixes.
+	(bidi_cache_idx, bidi_cache_last_idx, bidi_cache_fetch_state)
+	(bidi_cache_search, bidi_cache_find_level_change)
+	(bidi_cache_iterator_state, bidi_cache_find)
+	(bidi_find_other_level_edge, bidi_dump_cached_states):
+	Don't arbitrarily limit cache indexes to int; use ptrdiff_t instead.
+	(bidi_cache_size): Use ptrdiff_t rather than size_t, as we prefer
+	signed integers.
+	(elsz): Make it a (signed) constant.
+	(bidi_cache_iterator_state): Check for size-calculation overflow.
+
+	* alloc.c: Integer signedness and overflow fixes.
+	Do not impose an arbitrary 32-bit limit on malloc sizes when debugging.
+	(__malloc_size_t): Default to size_t, not to int.
+	(pure_size, pure_bytes_used_before_overflow, stack_copy_size)
+	(Fgarbage_collect, mark_object_loop_halt, mark_object):
+	Prefer ptrdiff_t to size_t when either would do, as we prefer
+	signed integers.
+	(XMALLOC_OVERRUN_CHECK_OVERHEAD): New macro.
+	(xmalloc_overrun_check_header, xmalloc_overrun_check_trailer):
+	Now const.  Initialize with values that are in range even if char
+	is signed.
+	(XMALLOC_PUT_SIZE, XMALLOC_GET_SIZE): Remove, replacing with ...
+	(xmalloc_put_size, xmalloc_get_size): New functions.  All uses changed.
+	These functions do the right thing with sizes > 2**32.
+	(check_depth): Now ptrdiff_t, not int.
+	(overrun_check_malloc, overrun_check_realloc, overrun_check_free):
+	Adjust to new way of storing sizes.  Check for size overflow bugs
+	in rest of code.
+	(STRING_BYTES_MAX): Adjust to new overheads.  The old code was
+	slightly wrong anyway, as it missed one instance of
+	XMALLOC_OVERRUN_CHECK_OVERHEAD.
+	(refill_memory_reserve): Omit needless cast to size_t.
+	(mark_object_loop_halt): Mark as externally visible.
+
+	* xselect.c: Integer signedness and overflow fixes.
+	(Fx_register_dnd_atom, x_handle_dnd_message):
+	Use ptrdiff_t, not size_t, since we prefer signed.
+	(Fx_register_dnd_atom): Check for ptrdiff_t (and size_t) overflow.
+	* xterm.h (struct x_display_info): Use ptrdiff_t, not size_t, for
+	x_dnd_atoms_size and x_dnd_atoms_length.
+
+	* doprnt.c: Prefer signed to unsigned when either works.
+	* eval.c (verror):
+	* doprnt.c (doprnt):
+	* lisp.h (doprnt):
+	* xdisp.c (vmessage):
+	Use ptrdiff_t, not size_t, when using or implementing doprnt,
+	since the sizes cannot exceed ptrdiff_t bounds anyway, and we
+	prefer signed arithmetic to avoid comparison confusion.
+	* doprnt.c (doprnt): Avoid a "+ 1" that can't overflow,
+	but is a bit tricky.
+
+	* lisp.h (struct vectorlike_header, struct Lisp_Subr): Signed sizes.
+	Use EMACS_INT, not EMACS_UINT, for sizes.  The code works equally
+	well either way, and we prefer signed to unsigned.
+
+2011-07-14  Paul Eggert  <[email-masked]>
+
 	Assume freestanding C89 headers, string.h, stdlib.h.
 	* data.c, doprnt.c, floatfns.c, print.c:
 	Include float.h unconditionally.

=== modified file 'src/alloc.c'
--- src/alloc.c	2011-07-13 01:04:29 +0000
+++ src/alloc.c	2011-07-13 03:45:56 +0000
@@ -70,7 +70,7 @@
 #include <malloc.h>
 /* malloc.h #defines this as size_t, at least in glibc2.  */
 #ifndef __malloc_size_t
-#define __malloc_size_t int
+#define __malloc_size_t size_t
 #endif
 
 /* Specify maximum number of areas to mmap.  It would be nice to use a
@@ -214,12 +214,12 @@
 /* Pointer to the pure area, and its size.  */
 
 static char *purebeg;
-static size_t pure_size;
+static ptrdiff_t pure_size;
 
 /* Number of bytes of pure storage used before pure storage overflowed.
    If this is non-zero, this implies that an overflow occurred.  */
 
-static size_t pure_bytes_used_before_overflow;
+static ptrdiff_t pure_bytes_used_before_overflow;
 
 /* Value is non-zero if P points into pure space.  */
 
@@ -252,7 +252,7 @@
 
 #if MAX_SAVE_STACK > 0
 static char *stack_copy;
-static size_t stack_copy_size;
+static ptrdiff_t stack_copy_size;
 #endif
 
 /* Non-zero means ignore malloc warnings.  Set during initialization.
@@ -486,14 +486,15 @@

 #ifndef XMALLOC_OVERRUN_CHECK
-#define XMALLOC_OVERRUN_CHECK_SIZE 0
+#define XMALLOC_OVERRUN_CHECK_OVERHEAD 0
 #else
 
-/* Check for overrun in malloc'ed buffers by wrapping a 16 byte header
-   and a 16 byte trailer around each block.
+/* Check for overrun in malloc'ed buffers by wrapping a header and trailer
+   around each block.
 
-   The header consists of 12 fixed bytes + a 4 byte integer contaning the
-   original block size, while the trailer consists of 16 fixed bytes.
+   The header consists of 16 fixed bytes followed by sizeof (size_t) bytes
+   containing the original block size in little-endian order,
+   while the trailer consists of 16 fixed bytes.
 
    The header is used to detect whether this block has been allocated
    through these functions -- as it seems that some low-level libc
@@ -502,31 +503,47 @@

 #define XMALLOC_OVERRUN_CHECK_SIZE 16
-
-static char xmalloc_overrun_check_header[XMALLOC_OVERRUN_CHECK_SIZE-4] =
-  { 0x9a, 0x9b, 0xae, 0xaf,
-    0xbf, 0xbe, 0xce, 0xcf,
-    0xea, 0xeb, 0xec, 0xed };
-
-static char xmalloc_overrun_check_trailer[XMALLOC_OVERRUN_CHECK_SIZE] =
-  { 0xaa, 0xab, 0xac, 0xad,
-    0xba, 0xbb, 0xbc, 0xbd,
-    0xca, 0xcb, 0xcc, 0xcd,
-    0xda, 0xdb, 0xdc, 0xdd };
-
-/* Macros to insert and extract the block size in the header.  */
-
-#define XMALLOC_PUT_SIZE(ptr, size)	\
-  (ptr[-1] = (size & 0xff),		\
-   ptr[-2] = ((size >> 8) & 0xff),	\
-   ptr[-3] = ((size >> 16) & 0xff),	\
-   ptr[-4] = ((size >> 24) & 0xff))
-
-#define XMALLOC_GET_SIZE(ptr)			\
-  (size_t)((unsigned)(ptr[-1])		|	\
-	   ((unsigned)(ptr[-2]) << 8)	|	\
-	   ((unsigned)(ptr[-3]) << 16)	|	\
-	   ((unsigned)(ptr[-4]) << 24))
+#define XMALLOC_OVERRUN_CHECK_OVERHEAD \
+  (2 * XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t))
+
+static char const xmalloc_overrun_check_header[XMALLOC_OVERRUN_CHECK_SIZE] =
+  { '\x9a', '\x9b', '\xae', '\xaf',
+    '\xbf', '\xbe', '\xce', '\xcf',
+    '\xea', '\xeb', '\xec', '\xed',
+    '\xdf', '\xde', '\x9c', '\x9d' };
+
+static char const xmalloc_overrun_check_trailer[XMALLOC_OVERRUN_CHECK_SIZE] =
+  { '\xaa', '\xab', '\xac', '\xad',
+    '\xba', '\xbb', '\xbc', '\xbd',
+    '\xca', '\xcb', '\xcc', '\xcd',
+    '\xda', '\xdb', '\xdc', '\xdd' };
+
+/* Insert and extract the block size in the header.  */
+
+static void
+xmalloc_put_size (unsigned char *ptr, size_t size)
+{
+  int i;
+  for (i = 0; i < sizeof (size_t); i++)
+    {
+      *--ptr = size & (1 << CHAR_BIT) - 1;
+      size >>= CHAR_BIT;
+    }
+}
+
+static size_t
+xmalloc_get_size (unsigned char *ptr)
+{
+  size_t size = 0;
+  int i;
+  ptr -= sizeof (size_t);
+  for (i = 0; i < sizeof (size_t); i++)
+    {
+      size <<= CHAR_BIT;
+      size += *ptr++;
+    }
+  return size;
+}

 /* The call depth in overrun_check functions.  For example, this might happen:
@@ -545,10 +562,10 @@
 
    xfree(10032)
      overrun_check_free(10032)
-       decrease overhed
+       decrease overhead
        free(10016)  <-  crash, because 10000 is the original pointer.  */
 
-static int check_depth;
+static ptrdiff_t check_depth;
 
 /* Like malloc, but wraps allocated block with header and trailer.  */
 
@@ -556,15 +573,16 @@
 overrun_check_malloc (size_t size)
 {
   register unsigned char *val;
-  size_t overhead = ++check_depth == 1 ? XMALLOC_OVERRUN_CHECK_SIZE*2 : 0;
+  int overhead = ++check_depth == 1 ? XMALLOC_OVERRUN_CHECK_OVERHEAD : 0;
+  if (SIZE_MAX - overhead < size)
+    abort ();
 
   val = (unsigned char *) malloc (size + overhead);
   if (val && check_depth == 1)
     {
-      memcpy (val, xmalloc_overrun_check_header,
-	      XMALLOC_OVERRUN_CHECK_SIZE - 4);
-      val += XMALLOC_OVERRUN_CHECK_SIZE;
-      XMALLOC_PUT_SIZE(val, size);
+      memcpy (val, xmalloc_overrun_check_header, XMALLOC_OVERRUN_CHECK_SIZE);
+      val += XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t);
+      xmalloc_put_size (val, size);
       memcpy (val + size, xmalloc_overrun_check_trailer,
 	      XMALLOC_OVERRUN_CHECK_SIZE);
     }
@@ -580,31 +598,32 @@
 overrun_check_realloc (POINTER_TYPE *block, size_t size)
 {
   register unsigned char *val = (unsigned char *) block;
-  size_t overhead = ++check_depth == 1 ? XMALLOC_OVERRUN_CHECK_SIZE*2 : 0;
+  int overhead = ++check_depth == 1 ? XMALLOC_OVERRUN_CHECK_OVERHEAD : 0;
+  if (SIZE_MAX - overhead < size)
+    abort ();
 
   if (val
       && check_depth == 1
       && memcmp (xmalloc_overrun_check_header,
-		 val - XMALLOC_OVERRUN_CHECK_SIZE,
-		 XMALLOC_OVERRUN_CHECK_SIZE - 4) == 0)
+		 val - XMALLOC_OVERRUN_CHECK_SIZE - sizeof (size_t),
+		 XMALLOC_OVERRUN_CHECK_SIZE) == 0)
     {
-      size_t osize = XMALLOC_GET_SIZE (val);
+      size_t osize = xmalloc_get_size (val);
       if (memcmp (xmalloc_overrun_check_trailer, val + osize,
 		  XMALLOC_OVERRUN_CHECK_SIZE))
 	abort ();
       memset (val + osize, 0, XMALLOC_OVERRUN_CHECK_SIZE);
-      val -= XMALLOC_OVERRUN_CHECK_SIZE;
-      memset (val, 0, XMALLOC_OVERRUN_CHECK_SIZE);
+      val -= XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t);
+      memset (val, 0, XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t));
     }
 
   val = (unsigned char *) realloc ((POINTER_TYPE *)val, size + overhead);
 
   if (val && check_depth == 1)
     {
-      memcpy (val, xmalloc_overrun_check_header,
-	      XMALLOC_OVERRUN_CHECK_SIZE - 4);
-      val += XMALLOC_OVERRUN_CHECK_SIZE;
-      XMALLOC_PUT_SIZE(val, size);
+      memcpy (val, xmalloc_overrun_check_header, XMALLOC_OVERRUN_CHECK_SIZE);
+      val += XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t);
+      xmalloc_put_size (val, size);
       memcpy (val + size, xmalloc_overrun_check_trailer,
 	      XMALLOC_OVERRUN_CHECK_SIZE);
     }
@@ -623,20 +642,20 @@
   if (val
       && check_depth == 1
       && memcmp (xmalloc_overrun_check_header,
-		 val - XMALLOC_OVERRUN_CHECK_SIZE,
-		 XMALLOC_OVERRUN_CHECK_SIZE - 4) == 0)
+		 val - XMALLOC_OVERRUN_CHECK_SIZE - sizeof (size_t),
+		 XMALLOC_OVERRUN_CHECK_SIZE) == 0)
     {
-      size_t osize = XMALLOC_GET_SIZE (val);
+      size_t osize = xmalloc_get_size (val);
       if (memcmp (xmalloc_overrun_check_trailer, val + osize,
 		  XMALLOC_OVERRUN_CHECK_SIZE))
 	abort ();
 #ifdef XMALLOC_CLEAR_FREE_MEMORY
-      val -= XMALLOC_OVERRUN_CHECK_SIZE;
-      memset (val, 0xff, osize + XMALLOC_OVERRUN_CHECK_SIZE*2);
+      val -= XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t);
+      memset (val, 0xff, osize + XMALLOC_OVERRUN_CHECK_OVERHEAD);
 #else
       memset (val + osize, 0, XMALLOC_OVERRUN_CHECK_SIZE);
-      val -= XMALLOC_OVERRUN_CHECK_SIZE;
-      memset (val, 0, XMALLOC_OVERRUN_CHECK_SIZE);
+      val -= XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t);
+      memset (val, 0, XMALLOC_OVERRUN_CHECK_SIZE + sizeof (size_t));
 #endif
     }
 
@@ -1661,7 +1680,8 @@
    calculating a value to be passed to malloc.  */
 #define STRING_BYTES_MAX					  \
   min (STRING_BYTES_BOUND,					  \
-       ((SIZE_MAX - XMALLOC_OVERRUN_CHECK_SIZE - GC_STRING_EXTRA  \
+       ((SIZE_MAX - XMALLOC_OVERRUN_CHECK_OVERHEAD		  \
+	 - GC_STRING_EXTRA					  \
 	 - offsetof (struct sblock, first_data)			  \
 	 - SDATA_DATA_OFFSET)					  \
 	& ~(sizeof (EMACS_INT) - 1)))
@@ -3320,7 +3340,7 @@
 {
 #ifndef SYSTEM_MALLOC
   if (spare_memory[0] == 0)
-    spare_memory[0] = (char *) malloc ((size_t) SPARE_MEMORY);
+    spare_memory[0] = (char *) malloc (SPARE_MEMORY);
   if (spare_memory[1] == 0)
     spare_memory[1] = (char *) lisp_align_malloc (sizeof (struct cons_block),
 						  MEM_TYPE_CONS);
@@ -4922,7 +4942,7 @@
   if (NILP (Vpurify_flag))
     {
       char *stack;
-      size_t stack_size;
+      ptrdiff_t stack_size;
       if (&stack_top_variable < stack_bottom)
 	{
 	  stack = &stack_top_variable;
@@ -5233,7 +5253,7 @@
    links of a list, in mark_object.  In debugging,
    the call to abort will hit a breakpoint.
    Normally this is zero and the check never goes off.  */
-static size_t mark_object_loop_halt;
+ptrdiff_t mark_object_loop_halt EXTERNALLY_VISIBLE;
 
 static void
 mark_vectorlike (struct Lisp_Vector *ptr)
@@ -5290,7 +5310,7 @@
   void *po;
   struct mem_node *m;
 #endif
-  size_t cdr_count = 0;
+  ptrdiff_t cdr_count = 0;
 
  loop:

=== modified file 'src/bidi.c'
--- src/bidi.c	2011-06-26 17:23:40 +0000
+++ src/bidi.c	2011-07-12 17:35:56 +0000
@@ -263,10 +263,10 @@
 
 #define BIDI_CACHE_CHUNK 200
 static struct bidi_it *bidi_cache;
-static size_t bidi_cache_size = 0;
-static size_t elsz = sizeof (struct bidi_it);
-static int bidi_cache_idx;	/* next unused cache slot */
-static int bidi_cache_last_idx;	/* slot of last cache hit */
+static ptrdiff_t bidi_cache_size = 0;
+enum { elsz = sizeof (struct bidi_it) };
+static ptrdiff_t bidi_cache_idx;	/* next unused cache slot */
+static ptrdiff_t bidi_cache_last_idx;	/* slot of last cache hit */
 
 static inline void
 bidi_cache_reset (void)
@@ -288,7 +288,7 @@
 }
 
 static inline void
-bidi_cache_fetch_state (int idx, struct bidi_it *bidi_it)
+bidi_cache_fetch_state (ptrdiff_t idx, struct bidi_it *bidi_it)
 {
   int current_scan_dir = bidi_it->scan_dir;
 
@@ -304,10 +304,10 @@
    level less or equal to LEVEL.  if LEVEL is -1, disregard the
    resolved levels in cached states.  DIR, if non-zero, means search
    in that direction from the last cache hit.  */
-static inline int
+static inline ptrdiff_t
 bidi_cache_search (EMACS_INT charpos, int level, int dir)
 {
-  int i, i_start;
+  ptrdiff_t i, i_start;
 
   if (bidi_cache_idx)
     {
@@ -366,12 +366,12 @@
    C, searching backwards (DIR = -1) for LEVEL = 2 will return the
    index of slot B or A, depending whether BEFORE is, respectively,
    non-zero or zero.  */
-static int
+static ptrdiff_t
 bidi_cache_find_level_change (int level, int dir, int before)
 {
   if (bidi_cache_idx)
     {
-      int i = dir ? bidi_cache_last_idx : bidi_cache_idx - 1;
+      ptrdiff_t i = dir ? bidi_cache_last_idx : bidi_cache_idx - 1;
       int incr = before ? 1 : 0;
 
       if (!dir)
@@ -407,7 +407,7 @@
 static inline void
 bidi_cache_iterator_state (struct bidi_it *bidi_it, int resolved)
 {
-  int idx;
+  ptrdiff_t idx;
 
   /* We should never cache on backward scans.  */
   if (bidi_it->scan_dir == -1)
@@ -420,6 +420,9 @@
       /* Enlarge the cache as needed.  */
       if (idx >= bidi_cache_size)
 	{
+	  if (min (PTRDIFF_MAX, SIZE_MAX) / elsz - BIDI_CACHE_CHUNK
+	      < bidi_cache_size)
+	    memory_full (SIZE_MAX);
 	  bidi_cache_size += BIDI_CACHE_CHUNK;
 	  bidi_cache =
 	    (struct bidi_it *) xrealloc (bidi_cache, bidi_cache_size * elsz);
@@ -468,7 +471,7 @@
 static inline bidi_type_t
 bidi_cache_find (EMACS_INT charpos, int level, struct bidi_it *bidi_it)
 {
-  int i = bidi_cache_search (charpos, level, bidi_it->scan_dir);
+  ptrdiff_t i = bidi_cache_search (charpos, level, bidi_it->scan_dir);
 
   if (i >= 0)
     {
@@ -1756,7 +1759,7 @@
 bidi_find_other_level_edge (struct bidi_it *bidi_it, int level, int end_flag)
 {
   int dir = end_flag ? -bidi_it->scan_dir : bidi_it->scan_dir;
-  int idx;
+  ptrdiff_t idx;
 
   /* Try the cache first.  */
   if ((idx = bidi_cache_find_level_change (level, dir, end_flag)) >= 0)
@@ -1912,7 +1915,7 @@
 void
 bidi_dump_cached_states (void)
 {
-  int i;
+  ptrdiff_t i;
   int ndigits = 1;
 
   if (bidi_cache_idx == 0)
@@ -1920,7 +1923,7 @@
       fprintf (stderr, "The cache is empty.\n");
       return;
     }
-  fprintf (stderr, "Total of %d state%s in cache:\n",
+  fprintf (stderr, "Total of %"pD"d state%s in cache:\n",
 	   bidi_cache_idx, bidi_cache_idx == 1 ? "" : "s");
 
   for (i = bidi_cache[bidi_cache_idx - 1].charpos; i > 0; i /= 10)

=== modified file 'src/buffer.c'
--- src/buffer.c	2011-07-13 04:09:28 +0000
+++ src/buffer.c	2011-07-14 06:41:47 +0000
@@ -152,7 +152,7 @@
 Lisp_Object Qinsert_in_front_hooks;
 Lisp_Object Qinsert_behind_hooks;
 
-static void alloc_buffer_text (struct buffer *, size_t);
+static void alloc_buffer_text (struct buffer *, ptrdiff_t);
 static void free_buffer_text (struct buffer *b);
 static struct Lisp_Overlay * copy_overlays (struct buffer *, struct Lisp_Overlay *);
 static void modify_overlay (struct buffer *, EMACS_INT, EMACS_INT);
@@ -4796,7 +4796,7 @@
 /* Allocate NBYTES bytes for buffer B's text buffer.  */
 
 static void
-alloc_buffer_text (struct buffer *b, size_t nbytes)
+alloc_buffer_text (struct buffer *b, ptrdiff_t nbytes)
 {
   POINTER_TYPE *p;
 
@@ -4826,8 +4826,8 @@
 enlarge_buffer_text (struct buffer *b, EMACS_INT delta)
 {
   POINTER_TYPE *p;
-  size_t nbytes = (BUF_Z_BYTE (b) - BUF_BEG_BYTE (b) + BUF_GAP_SIZE (b) + 1
-		   + delta);
+  ptrdiff_t nbytes = (BUF_Z_BYTE (b) - BUF_BEG_BYTE (b) + BUF_GAP_SIZE (b) + 1
+		      + delta);
   BLOCK_INPUT;
 #if defined USE_MMAP_FOR_BUFFERS
   p = mmap_realloc ((POINTER_TYPE **) &b->text->beg, nbytes);

=== modified file 'src/callint.c'
--- src/callint.c	2011-07-07 16:59:26 +0000
+++ src/callint.c	2011-07-09 07:06:04 +0000
@@ -339,7 +339,7 @@
     {
       Lisp_Object input;
       Lisp_Object funval = Findirect_function (function, Qt);
-      size_t events = num_input_events;
+      uintmax_t events = num_input_events;
       input = specs;
       /* Compute the arg values using the user's expression.  */
       GCPRO2 (input, filter_specs);

=== modified file 'src/dispnew.c'
--- src/dispnew.c	2011-07-10 08:20:10 +0000
+++ src/dispnew.c	2011-07-11 18:36:33 +0000
@@ -103,57 +103,24 @@
 
 /* Function prototypes.  */
 
-static struct glyph_matrix *save_current_matrix (struct frame *);
-static void restore_current_matrix (struct frame *, struct glyph_matrix *);
-static int showing_window_margins_p (struct window *);
-static void fake_current_matrices (Lisp_Object);
-static void redraw_overlapping_rows (struct window *, int);
-static void redraw_overlapped_rows (struct window *, int);
-static int count_blanks (struct glyph *, int);
-static int count_match (struct glyph *, struct glyph *,
-                        struct glyph *, struct glyph *);
-static unsigned line_draw_cost (struct glyph_matrix *, int);
 static void update_frame_line (struct frame *, int);
-static struct dim allocate_matrices_for_frame_redisplay
-     (Lisp_Object, int, int, int, int *);
 static int required_matrix_height (struct window *);
 static int required_matrix_width (struct window *);
-static void allocate_matrices_for_window_redisplay (struct window *);
-static int realloc_glyph_pool (struct glyph_pool *, struct dim);
 static void adjust_frame_glyphs (struct frame *);
-static struct glyph_matrix *new_glyph_matrix (struct glyph_pool *);
-static void free_glyph_matrix (struct glyph_matrix *);
-static void adjust_glyph_matrix (struct window *, struct glyph_matrix *,
-                                 int, int, struct dim);
 static void change_frame_size_1 (struct frame *, int, int, int, int, int);
 static void increment_row_positions (struct glyph_row *, EMACS_INT, EMACS_INT);
-static void swap_glyph_pointers (struct glyph_row *, struct glyph_row *);
-#if GLYPH_DEBUG
-static int glyph_row_slice_p (struct glyph_row *, struct glyph_row *);
-#endif
 static void fill_up_frame_row_with_spaces (struct glyph_row *, int);
 static void build_frame_matrix_from_window_tree (struct glyph_matrix *,
                                                  struct window *);
 static void build_frame_matrix_from_leaf_window (struct glyph_matrix *,
                                                  struct window *);
-static struct glyph_pool *new_glyph_pool (void);
-static void free_glyph_pool (struct glyph_pool *);
-static void adjust_frame_glyphs_initially (void);
 static void adjust_frame_message_buffer (struct frame *);
 static void adjust_decode_mode_spec_buffer (struct frame *);
 static void fill_up_glyph_row_with_spaces (struct glyph_row *);
-static void build_frame_matrix (struct frame *);
-void clear_current_matrices (struct frame *);
-void scroll_glyph_matrix_range (struct glyph_matrix *, int, int,
-                                int, int);
 static void clear_window_matrices (struct window *, int);
 static void fill_up_glyph_row_area_with_spaces (struct glyph_row *, int);
 static int scrolling_window (struct window *, int);
 static int update_window_line (struct window *, int, int *);
-static void update_marginal_area (struct window *, int, int);
-static int update_text_area (struct window *, int);
-static void make_current (struct glyph_matrix *, struct glyph_matrix *,
-                          int);
 static void mirror_make_current (struct window *, int);
 #if GLYPH_DEBUG
 static void check_matrix_pointers (struct glyph_matrix *,
@@ -286,7 +253,7 @@
 /* A tick that's incremented each time something is added to the
    history.  */
 
-static unsigned history_tick;
+static uprintmax_t history_tick;
 
 static void add_frame_display_history (struct frame *, int);
 
@@ -305,7 +272,7 @@
   buf = redisplay_history[history_idx].trace;
   ++history_idx;
 
-  sprintf (buf, "%d: window %p (`%s')%s\n",
+  sprintf (buf, "%"pMu": window %p (`%s')%s\n",
 	   history_tick++,
 	   w,
 	   ((BUFFERP (w->buffer)
@@ -331,7 +298,7 @@
   buf = redisplay_history[history_idx].trace;
   ++history_idx;
 
-  sprintf (buf, "%d: update frame %p%s",
+  sprintf (buf, "%"pMu": update frame %p%s",
 	   history_tick++,
 	   f, paused_p ? " ***paused***" : "");
 }
@@ -532,7 +499,7 @@
   /* Enlarge MATRIX->rows if necessary.  New rows are cleared.  */
   if (matrix->rows_allocated < dim.height)
     {
-      int size = dim.height * sizeof (struct glyph_row);
+      ptrdiff_t size = dim.height * sizeof (struct glyph_row);
       new_rows = dim.height - matrix->rows_allocated;
       matrix->rows = (struct glyph_row *) xrealloc (matrix->rows, size);
       memset (matrix->rows + matrix->rows_allocated, 0,
@@ -1198,7 +1165,7 @@
 {
   if (!row->enabled_p)
     {
-      unsigned rp = row->reversed_p;
+      int rp = row->reversed_p;
 
       clear_glyph_row (row);
       row->enabled_p = 1;
@@ -1242,7 +1209,7 @@
    the number of characters in the line.  If must_write_spaces is
    zero, leading and trailing spaces are ignored.  */
 
-static unsigned int
+static int
 line_draw_cost (struct glyph_matrix *matrix, int vpos)
 {
   struct glyph_row *row = matrix->rows + vpos;
@@ -1435,7 +1402,7 @@
   needed = matrix_dim.width * matrix_dim.height;
   if (needed > pool->nglyphs)
     {
-      int size = needed * sizeof (struct glyph);
+      ptrdiff_t size = needed * sizeof (struct glyph);
 
       if (pool->glyphs)
 	{
@@ -2061,7 +2028,7 @@
     {
       struct glyph_row *from = f->current_matrix->rows + i;
       struct glyph_row *to = saved->rows + i;
-      size_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph);
+      ptrdiff_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph);
       to->glyphs[TEXT_AREA] = (struct glyph *) xmalloc (nbytes);
       memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA], nbytes);
       to->used[TEXT_AREA] = from->used[TEXT_AREA];
@@ -2083,7 +2050,7 @@
     {
       struct glyph_row *from = saved->rows + i;
       struct glyph_row *to = f->current_matrix->rows + i;
-      size_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph);
+      ptrdiff_t nbytes = from->used[TEXT_AREA] * sizeof (struct glyph);
       memcpy (to->glyphs[TEXT_AREA], from->glyphs[TEXT_AREA], nbytes);
       to->used[TEXT_AREA] = from->used[TEXT_AREA];
       xfree (from->glyphs[TEXT_AREA]);
@@ -2271,7 +2238,7 @@
 static void
 adjust_frame_message_buffer (struct frame *f)
 {
-  int size = FRAME_MESSAGE_BUF_SIZE (f) + 1;
+  ptrdiff_t size = FRAME_MESSAGE_BUF_SIZE (f) + 1;
 
   if (FRAME_MESSAGE_BUF (f))
     {
@@ -4301,7 +4268,8 @@
   struct glyph_matrix *current_matrix = w->current_matrix;
   int yb = window_text_bottom_y (w);
   int i, j, first_old, first_new, last_old, last_new;
-  int nruns, nbytes, n, run_idx;
+  int nruns, n, run_idx;
+  ptrdiff_t nbytes;
   struct row_entry *entry;
   struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
 
@@ -6326,11 +6294,14 @@
     int width = FRAME_TOTAL_COLS (sf);
     int height = FRAME_LINES (sf);
 
-    unsigned int total_glyphs = height * (width + 2) * sizeof (struct glyph);
-
     /* If these sizes are so big they cause overflow, just ignore the
-       change.  It's not clear what better we could do.  */
-    if (total_glyphs / sizeof (struct glyph) / height != width + 2)
+       change.  It's not clear what better we could do.  The rest of
+       the code assumes that (width + 2) * height * sizeof (struct glyph)
+       does not overflow and does not exceed PTRDIFF_MAX or SIZE_MAX.  */
+    if (INT_ADD_RANGE_OVERFLOW (width, 2, INT_MIN, INT_MAX)
+	|| INT_MULTIPLY_RANGE_OVERFLOW (width + 2, height, INT_MIN, INT_MAX)
+	|| (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (struct glyph)
+	    < (width + 2) * height))
       fatal ("screen size %dx%d too big", width, height);
   }

=== modified file 'src/doprnt.c'
--- src/doprnt.c	2011-07-14 07:31:04 +0000
+++ src/doprnt.c	2011-07-14 07:50:51 +0000
@@ -129,8 +129,8 @@
    String arguments are passed as C strings.
    Integers are passed as C integers.  */
 
-size_t
-doprnt (char *buffer, register size_t bufsize, const char *format,
+ptrdiff_t
+doprnt (char *buffer, ptrdiff_t bufsize, const char *format,
 	const char *format_end, va_list ap)
 {
   const char *fmt = format;	/* Pointer into format string */
@@ -140,7 +140,7 @@
   char tembuf[DBL_MAX_10_EXP + 100];
 
   /* Size of sprintf_buffer.  */
-  size_t size_allocated = sizeof (tembuf);
+  ptrdiff_t size_allocated = sizeof (tembuf);
 
   /* Buffer to use for sprintf.  Either tembuf or same as BIG_BUFFER.  */
   char *sprintf_buffer = tembuf;
@@ -159,7 +159,7 @@
   if (format_end == 0)
     format_end = format + strlen (format);
 
-  if ((format_end - format + 1) < sizeof (fixed_buffer))
+  if (format_end - format < sizeof (fixed_buffer) - 1)
     fmtcpy = fixed_buffer;
   else
     SAFE_ALLOCA (fmtcpy, char *, format_end - format + 1);
@@ -171,7 +171,7 @@
     {
       if (*fmt == '%')	/* Check for a '%' character */
 	{
-	  size_t size_bound = 0;
+	  ptrdiff_t size_bound = 0;
 	  EMACS_INT width;  /* Columns occupied by STRING on display.  */
 	  int long_flag = 0;
 	  int pIlen = sizeof pI - 1;
@@ -189,16 +189,16 @@
 		     This might be a field width or a precision; e.g.
 		     %1.1000f and %1000.1f both might need 1000+ bytes.
 		     Parse the width or precision, checking for overflow.  */
-		  size_t n = *fmt - '0';
+		  ptrdiff_t n = *fmt - '0';
 		  while (fmt + 1 < format_end
 			 && '0' <= fmt[1] && fmt[1] <= '9')
 		    {
-		      /* Avoid size_t overflow.  Avoid int overflow too, as
+		      /* Avoid ptrdiff_t, size_t, and int overflow, as
 			 many sprintfs mishandle widths greater than INT_MAX.
 			 This test is simple but slightly conservative: e.g.,
 			 (INT_MAX - INT_MAX % 10) is reported as an overflow
 			 even when it's not.  */
-		      if (n >= min (INT_MAX, SIZE_MAX) / 10)
+		      if (n >= min (INT_MAX, min (PTRDIFF_MAX, SIZE_MAX)) / 10)
 			error ("Format width or precision too large");
 		      n = n * 10 + fmt[1] - '0';
 		      *string++ = *++fmt;
@@ -230,7 +230,7 @@
 
 	  /* Make the size bound large enough to handle floating point formats
 	     with large numbers.  */
-	  if (size_bound > SIZE_MAX - DBL_MAX_10_EXP - 50)
+	  if (size_bound > min (PTRDIFF_MAX, SIZE_MAX) - DBL_MAX_10_EXP - 50)
 	    error ("Format width or precision too large");
 	  size_bound += DBL_MAX_10_EXP + 50;

=== modified file 'src/editfns.c'
--- src/editfns.c	2011-07-13 23:48:35 +0000
+++ src/editfns.c	2011-07-14 06:41:47 +0000
@@ -3510,22 +3510,6 @@
   RETURN_UNGCPRO (string);
 }
 
-/* pWIDE is a conversion for printing large decimal integers (possibly with a
-   trailing "d" that is ignored).  pWIDElen is its length.  signed_wide and
-   unsigned_wide are signed and unsigned types for printing them.  Use widest
-   integers if available so that more floating point values can be converted.  */
-#ifdef PRIdMAX
-# define pWIDE PRIdMAX
-enum { pWIDElen = sizeof PRIdMAX - 2 }; /* Don't count trailing "d".  */
-typedef intmax_t signed_wide;
-typedef uintmax_t unsigned_wide;
-#else
-# define pWIDE pI
-enum { pWIDElen = sizeof pI - 1 };
-typedef EMACS_INT signed_wide;
-typedef EMACS_UINT unsigned_wide;
-#endif
-
 DEFUN ("format", Fformat, Sformat, 1, MANY, 0,
        doc: /* Format a string out of a format-string and arguments.
 The first argument is a format control string.
@@ -3907,7 +3891,11 @@
 		   precision is no more than DBL_USEFUL_PRECISION_MAX.
 		   On all practical hosts, %f is the worst case.  */
 		SPRINTF_BUFSIZE =
-		  sizeof "-." + (DBL_MAX_10_EXP + 1) + USEFUL_PRECISION_MAX
+		  sizeof "-." + (DBL_MAX_10_EXP + 1) + USEFUL_PRECISION_MAX,
+
+		/* Length of pM (that is, of pMd without the
+		   trailing "d").  */
+		pMlen = sizeof pMd - 2
 	      };
 	      verify (0 < USEFUL_PRECISION_MAX);
 
@@ -3920,7 +3908,7 @@
 
 	      /* Copy of conversion specification, modified somewhat.
 		 At most three flags F can be specified at once.  */
-	      char convspec[sizeof "%FFF.*d" + pWIDElen];
+	      char convspec[sizeof "%FFF.*d" + pMlen];
 
 	      /* Avoid undefined behavior in underlying sprintf.  */
 	      if (conversion == 'd' || conversion == 'i')
@@ -3928,7 +3916,7 @@
 
 	      /* Create the copy of the conversion specification, with
 		 any width and precision removed, with ".*" inserted,
-		 and with pWIDE inserted for integer formats.  */
+		 and with pM inserted for integer formats.  */
 	      {
 		char *f = convspec;
 		*f++ = '%';
@@ -3943,8 +3931,8 @@
 		    || conversion == 'o' || conversion == 'x'
 		    || conversion == 'X')
 		  {
-		    memcpy (f, pWIDE, pWIDElen);
-		    f += pWIDElen;
+		    memcpy (f, pMd, pMlen);
+		    f += pMlen;
 		    zero_flag &= ~ precision_given;
 		  }
 		*f++ = conversion;
@@ -3984,7 +3972,7 @@
 		  /* For float, maybe we should use "%1.0f"
 		     instead so it also works for values outside
 		     the integer range.  */
-		  signed_wide x;
+		  printmax_t x;
 		  if (INTEGERP (args[n]))
 		    x = XINT (args[n]);
 		  else
@@ -3992,13 +3980,13 @@
 		      double d = XFLOAT_DATA (args[n]);
 		      if (d < 0)
 			{
-			  x = TYPE_MINIMUM (signed_wide);
+			  x = TYPE_MINIMUM (printmax_t);
 			  if (x < d)
 			    x = d;
 			}
 		      else
 			{
-			  x = TYPE_MAXIMUM (signed_wide);
+			  x = TYPE_MAXIMUM (printmax_t);
 			  if (d < x)
 			    x = d;
 			}
@@ -4008,7 +3996,7 @@
 	      else
 		{
 		  /* Don't sign-extend for octal or hex printing.  */
-		  unsigned_wide x;
+		  uprintmax_t x;
 		  if (INTEGERP (args[n]))
 		    x = XUINT (args[n]);
 		  else
@@ -4018,7 +4006,7 @@
 			x = 0;
 		      else
 			{
-			  x = TYPE_MAXIMUM (unsigned_wide);
+			  x = TYPE_MAXIMUM (uprintmax_t);
 			  if (d < x)
 			    x = d;
 			}

=== modified file 'src/emacs.c'
--- src/emacs.c	2011-07-10 08:20:10 +0000
+++ src/emacs.c	2011-07-11 06:05:57 +0000
@@ -170,8 +170,10 @@
 /* The address where the heap starts (from the first sbrk (0) call).  */
 static void *my_heap_start;
 
+#ifdef GNU_LINUX
 /* The gap between BSS end and heap start as far as we can tell.  */
-static unsigned long heap_bss_diff;
+static uprintmax_t heap_bss_diff;
+#endif
 
 /* Nonzero means running Emacs without interactive terminal.  */
 int noninteractive;
@@ -716,6 +718,7 @@
   setenv ("G_SLICE", "always-malloc", 1);
 #endif
 
+#ifdef GNU_LINUX
   if (!initialized)
     {
       extern char my_endbss[];
@@ -726,6 +729,7 @@
 
       heap_bss_diff = (char *)my_heap_start - max (my_endbss, my_endbss_static);
     }
+#endif
 
 #ifdef RUN_TIME_REMAP
   if (initialized)
@@ -2134,7 +2138,7 @@
     {
       fprintf (stderr, "**************************************************\n");
       fprintf (stderr, "Warning: Your system has a gap between BSS and the\n");
-      fprintf (stderr, "heap (%lu bytes).  This usually means that exec-shield\n",
+      fprintf (stderr, "heap (%"pMu" bytes).  This usually means that exec-shield\n",
                heap_bss_diff);
       fprintf (stderr, "or something similar is in effect.  The dump may\n");
       fprintf (stderr, "fail because of this.  See the section about\n");

=== modified file 'src/eval.c'
--- src/eval.c	2011-07-05 09:51:56 +0000
+++ src/eval.c	2011-07-07 02:14:52 +0000
@@ -1968,18 +1968,18 @@
 verror (const char *m, va_list ap)
 {
   char buf[4000];
-  size_t size = sizeof buf;
-  size_t size_max = STRING_BYTES_BOUND + 1;
-  size_t mlen = strlen (m);
+  ptrdiff_t size = sizeof buf;
+  ptrdiff_t size_max = STRING_BYTES_BOUND + 1;
+  char const *m_end = m + strlen (m);
   char *buffer = buf;
-  size_t used;
+  ptrdiff_t used;
   Lisp_Object string;
 
   while (1)
     {
       va_list ap_copy;
       va_copy (ap_copy, ap);
-      used = doprnt (buffer, size, m, m + mlen, ap_copy);
+      used = doprnt (buffer, size, m, m_end, ap_copy);
       va_end (ap_copy);
 
       /* Note: the -1 below is because `doprnt' returns the number of bytes

=== modified file 'src/fileio.c'
--- src/fileio.c	2011-07-04 17:50:12 +0000
+++ src/fileio.c	2011-07-07 21:52:44 +0000
@@ -587,9 +587,9 @@
 {
   Lisp_Object val;
   int len, clen;
-  intmax_t pid;
+  printmax_t pid;
   char *p, *data;
-  char pidbuf[INT_BUFSIZE_BOUND (pid_t)];
+  char pidbuf[INT_BUFSIZE_BOUND (printmax_t)];
   int pidlen;
 
   CHECK_STRING (prefix);
@@ -611,7 +611,7 @@
   else
     {
 #ifdef HAVE_LONG_FILE_NAMES
-      pidlen = sprintf (pidbuf, "%"PRIdMAX, pid);
+      pidlen = sprintf (pidbuf, "%"pMd, pid);
 #else
       pidbuf[0] = make_temp_name_tbl[pid & 63], pid >>= 6;
       pidbuf[1] = make_temp_name_tbl[pid & 63], pid >>= 6;

=== modified file 'src/filelock.c'
--- src/filelock.c	2011-06-20 03:11:40 +0000
+++ src/filelock.c	2011-07-07 21:52:44 +0000
@@ -337,7 +337,7 @@
 lock_file_1 (char *lfname, int force)
 {
   register int err;
-  intmax_t boot, pid;
+  printmax_t boot, pid;
   const char *user_name;
   const char *host_name;
   char *lock_info_str;
@@ -354,15 +354,15 @@
   else
     host_name = "";
   lock_info_str = (char *)alloca (strlen (user_name) + strlen (host_name)
-				  + 2 * INT_STRLEN_BOUND (intmax_t)
+				  + 2 * INT_STRLEN_BOUND (printmax_t)
 				  + sizeof "@.:");
   pid = getpid ();
 
   if (boot)
-    sprintf (lock_info_str, "%s@%s.%"PRIdMAX":%"PRIdMAX,
+    sprintf (lock_info_str, "%s@%s.%"pMd":%"pMd,
 	     user_name, host_name, pid, boot);
   else
-    sprintf (lock_info_str, "%s@%s.%"PRIdMAX,
+    sprintf (lock_info_str, "%s@%s.%"pMd,
 	     user_name, host_name, pid);
 
   err = symlink (lock_info_str, lfname);
@@ -542,7 +542,7 @@
   register Lisp_Object attack, orig_fn, encoded_fn;
   register char *lfname, *locker;
   lock_info_type lock_info;
-  intmax_t pid;
+  printmax_t pid;
   struct gcpro gcpro1;
 
   /* Don't do locking while dumping Emacs.
@@ -581,9 +581,10 @@
 
   /* Else consider breaking the lock */
   locker = (char *) alloca (strlen (lock_info.user) + strlen (lock_info.host)
-			    + INT_STRLEN_BOUND (intmax_t) + sizeof "@ (pid )");
+			    + INT_STRLEN_BOUND (printmax_t)
+			    + sizeof "@ (pid )");
   pid = lock_info.pid;
-  sprintf (locker, "%s@%s (pid %"PRIdMAX")",
+  sprintf (locker, "%s@%s (pid %"pMd")",
 	   lock_info.user, lock_info.host, pid);
   FREE_LOCK_INFO (lock_info);

=== modified file 'src/fns.c'
--- src/fns.c	2011-07-05 02:51:15 +0000
+++ src/fns.c	2011-07-08 00:51:25 +0000
@@ -4098,25 +4098,33 @@
 #define SXHASH_REDUCE(X) \
   ((((X) ^ (X) >> (BITS_PER_EMACS_INT - FIXNUM_BITS))) & INTMASK)
 
-/* Return a hash for string PTR which has length LEN.  The hash
-   code returned is guaranteed to fit in a Lisp integer.  */
+/* Return a hash for string PTR which has length LEN.  The hash value
+   can be any EMACS_UINT value.  */
 
-static EMACS_UINT
-sxhash_string (unsigned char *ptr, EMACS_INT len)
+EMACS_UINT
+hash_string (char const *ptr, ptrdiff_t len)
 {
-  unsigned char *p = ptr;
-  unsigned char *end = p + len;
+  char const *p = ptr;
+  char const *end = p + len;
   unsigned char c;
   EMACS_UINT hash = 0;
 
   while (p != end)
     {
       c = *p++;
-      if (c >= 0140)
-	c -= 40;
       hash = SXHASH_COMBINE (hash, c);
     }
 
+  return hash;
+}
+
+/* Return a hash for string PTR which has length LEN.  The hash
+   code returned is guaranteed to fit in a Lisp integer.  */
+
+static EMACS_UINT
+sxhash_string (char const *ptr, ptrdiff_t len)
+{
+  EMACS_UINT hash = hash_string (ptr, len);
   return SXHASH_REDUCE (hash);
 }
 
@@ -4231,7 +4239,7 @@
       /* Fall through.  */
 
     case Lisp_String:
-      hash = sxhash_string (SDATA (obj), SCHARS (obj));
+      hash = sxhash_string (SSDATA (obj), SBYTES (obj));
       break;
 
       /* This can be everything from a vector to an overlay.  */

=== modified file 'src/gtkutil.c'
--- src/gtkutil.c	2011-07-10 04:54:04 +0000
+++ src/gtkutil.c	2011-07-13 15:42:12 +0000
@@ -269,8 +269,8 @@
                                       GDK_COLORSPACE_RGB,
                                       FALSE,
                                       xim->bitmap_unit,
-                                      (int) width,
-                                      (int) height,
+                                      width,
+                                      height,
                                       xim->bytes_per_line,
                                       NULL,
                                       NULL);
@@ -3646,7 +3646,7 @@
 	      gtk_adjustment_set_page_size (adj, size);
 	      gtk_adjustment_set_step_increment (adj, new_step);
 	      /* Assume a page increment is about 95% of the page size  */
-	      gtk_adjustment_set_page_increment (adj,(int) (0.95*size));
+	      gtk_adjustment_set_page_increment (adj, size - size / 20);
 	      changed = 1;
 	    }
 	}

=== modified file 'src/image.c'
--- src/image.c	2011-07-10 08:20:10 +0000
+++ src/image.c	2011-07-14 06:20:53 +0000
@@ -136,7 +136,6 @@
 #ifdef COLOR_TABLE_SUPPORT
 static void free_color_table (void);
 static unsigned long *colors_in_color_table (int *n);
-static unsigned long lookup_pixel_color (struct frame *f, unsigned long p);
 #endif
 static Lisp_Object Finit_image_library (Lisp_Object, Lisp_Object);
 
@@ -987,7 +986,6 @@
  ***********************************************************************/
 
 static void free_image (struct frame *f, struct image *img);
-static int check_image_size (struct frame *f, int width, int height);
 
 #define MAX_IMAGE_SIZE 6.0
 /* Allocate and return a new image structure for image specification
@@ -1042,7 +1040,7 @@
 /* Return 1 if the given widths and heights are valid for display;
    otherwise, return 0. */
 
-int
+static int
 check_image_size (struct frame *f, int width, int height)
 {
   int w, h;
@@ -1051,23 +1049,18 @@
     return 0;
 
   if (INTEGERP (Vmax_image_size))
-    w = h = XINT (Vmax_image_size);
+    return (width <= XINT (Vmax_image_size)
+	    && height <= XINT (Vmax_image_size));
   else if (FLOATP (Vmax_image_size))
     {
-      if (f != NULL)
-	{
-	  w = FRAME_PIXEL_WIDTH (f);
-	  h = FRAME_PIXEL_HEIGHT (f);
-	}
-      else
-	w = h = 1024;  /* Arbitrary size for unknown frame. */
-      w = (int) (XFLOAT_DATA (Vmax_image_size) * w);
-      h = (int) (XFLOAT_DATA (Vmax_image_size) * h);
+      xassert (f);
+      w = FRAME_PIXEL_WIDTH (f);
+      h = FRAME_PIXEL_HEIGHT (f);
+      return (width <= XFLOAT_DATA (Vmax_image_size) * w
+	      && height <= XFLOAT_DATA (Vmax_image_size) * h);
     }
   else
     return 1;
-
-  return (width <= w && height <= h);
 }
 
 /* Prepare image IMG for display on frame F.  Must be called before
@@ -1368,7 +1361,9 @@
 
   xassert (STRINGP (color_name));
 
-  if (x_defined_color (f, SSDATA (color_name), &color, 1))
+  if (x_defined_color (f, SSDATA (color_name), &color, 1)
+      && img->ncolors < min (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *img->colors,
+			     INT_MAX))
     {
       /* This isn't called frequently so we get away with simply
 	 reallocating the color vector to the needed size, here.  */
@@ -1911,6 +1906,38 @@
 static void x_destroy_x_image (XImagePtr);
 static void x_put_x_image (struct frame *, XImagePtr, Pixmap, int, int);
 
+/* Return nonzero if XIMG's size WIDTH x HEIGHT doesn't break X.
+   WIDTH and HEIGHT must both be positive.
+   If XIMG is null, assume it is a bitmap.  */
+static int
+x_check_image_size (XImagePtr ximg, int width, int height)
+{
+  /* Respect Xlib's limits: it cannot deal with images that have more
+     than INT_MAX (and/or UINT_MAX) bytes.  And respect Emacs's limits
+     of PTRDIFF_MAX (and/or SIZE_MAX) bytes for any object.  For now,
+     assume all windowing systems have the same limits that X does.  */
+  enum
+  {
+    XLIB_BYTES_MAX = min (INT_MAX, UINT_MAX),
+    X_IMAGE_BYTES_MAX = min (XLIB_BYTES_MAX, min (PTRDIFF_MAX, SIZE_MAX))
+  };
+
+  int bitmap_pad, depth, bytes_per_line;
+  if (ximg)
+    {
+      bitmap_pad = ximg->bitmap_pad;
+      depth = ximg->depth;
+      bytes_per_line = ximg->bytes_per_line;
+    }
+  else
+    {
+      bitmap_pad = 8;
+      depth = 1;
+      bytes_per_line = (width >> 3) + ((width & 7) != 0);
+    }
+  return (width <= (INT_MAX - (bitmap_pad - 1)) / depth
+	  && height <= X_IMAGE_BYTES_MAX / bytes_per_line);
+}
 
 /* Create an XImage and a pixmap of size WIDTH x HEIGHT for use on
    frame F.  Set *XIMG and *PIXMAP to the XImage and Pixmap created.
@@ -1943,6 +1970,15 @@
       return 0;
     }
 
+  if (! x_check_image_size (*ximg, width, height))
+    {
+      x_destroy_x_image (*ximg);
+      *ximg = NULL;
+      image_error ("Image too large (%dx%d)",
+		   make_number (width), make_number (height));
+      return 0;
+    }
+
   /* Allocate image raster.  */
   (*ximg)->data = (char *) xmalloc ((*ximg)->bytes_per_line * height);
 
@@ -1989,11 +2025,6 @@
     palette_colors = 1 << depth - 1;
 
   *ximg = xmalloc (sizeof (XImage) + palette_colors * sizeof (RGBQUAD));
-  if (*ximg == NULL)
-    {
-      image_error ("Unable to allocate memory for XImage", Qnil, Qnil);
-      return 0;
-    }
 
   header = &(*ximg)->info.bmiHeader;
   memset (&(*ximg)->info, 0, sizeof (BITMAPINFO));
@@ -2365,7 +2396,7 @@
 	}
       else if (BOOL_VECTOR_P (data))
 	{
-	  if (XBOOL_VECTOR (data)->size < width * height)
+	  if (XBOOL_VECTOR (data)->size / height < width)
 	    return 0;
 	}
       else
@@ -2561,13 +2592,15 @@
   img->pixmap = ns_image_from_XBM (data, img->width, img->height);
 
 #else
-  img->pixmap
-    = XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f),
+  img->pixmap =
+   (x_check_image_size (0, img->width, img->height)
+    ? XCreatePixmapFromBitmapData (FRAME_X_DISPLAY (f),
 				   FRAME_X_WINDOW (f),
 				   data,
 				   img->width, img->height,
 				   fg, bg,
-				   DefaultDepthOfScreen (FRAME_X_SCREEN (f)));
+				   DefaultDepthOfScreen (FRAME_X_SCREEN (f)))
+    : NO_PIXMAP);
 #endif /* !HAVE_NTGUI && !HAVE_NS */
 }
 
@@ -2674,6 +2707,13 @@
   expect ('=');
   expect ('{');
 
+  if (! x_check_image_size (0, *width, *height))
+    {
+      if (!inhibit_image_error)
+	image_error ("Image too large (%dx%d)",
+		     make_number (*width), make_number (*height));
+      goto failure;
+    }
   bytes_per_line = (*width + 7) / 8 + padding_p;
   nbytes = bytes_per_line * *height;
   p = *data = (char *) xmalloc (nbytes);
@@ -2864,6 +2904,12 @@
 	  img->width = XFASTINT (fmt[XBM_WIDTH].value);
 	  img->height = XFASTINT (fmt[XBM_HEIGHT].value);
 	  xassert (img->width > 0 && img->height > 0);
+	  if (!check_image_size (f, img->width, img->height))
+	    {
+	      image_error ("Invalid image size (see `max-image-size')",
+			   Qnil, Qnil);
+	      return 0;
+	    }
 	}
 
       /* Get foreground and background colors, maybe allocate colors.  */
@@ -2925,9 +2971,13 @@
 #endif
 	  /* Create the pixmap.  */
 
-	  Create_Pixmap_From_Bitmap_Data (f, img, bits,
-					  foreground, background,
-					  non_default_colors);
+	  if (x_check_image_size (0, img->width, img->height))
+	    Create_Pixmap_From_Bitmap_Data (f, img, bits,
+					    foreground, background,
+					    non_default_colors);
+	  else
+	    img->pixmap = NO_PIXMAP;
+
 	  if (img->pixmap)
 	    success_p = 1;
 	  else
@@ -3125,12 +3175,8 @@
 static int
 xpm_color_bucket (char *color_name)
 {
-  unsigned h = 0;
-  char *s;
-
-  for (s = color_name; *s; ++s)
-    h = (h << 2) ^ *s;
-  return h %= XPM_COLOR_CACHE_BUCKETS;
+  EMACS_UINT hash = hash_string (color_name, strlen (color_name));
+  return hash % XPM_COLOR_CACHE_BUCKETS;
 }

@@ -3147,7 +3193,7 @@
   if (bucket < 0)
     bucket = xpm_color_bucket (color_name);
 
-  nbytes = sizeof *p + strlen (color_name);
+  nbytes = offsetof (struct xpm_cached_color, name) + strlen (color_name) + 1;
   p = (struct xpm_cached_color *) xmalloc (nbytes);
   strcpy (p->name, color_name);
   p->color = *color;
@@ -3849,6 +3895,18 @@
       goto failure;
     }
 
+  if (!x_create_x_image_and_pixmap (f, width, height, 0,
+				    &ximg, &img->pixmap)
+#ifndef HAVE_NS
+      || !x_create_x_image_and_pixmap (f, width, height, 1,
+				       &mask_img, &img->mask)
+#endif
+      )
+    {
+      image_error ("Image too large", Qnil, Qnil);
+      goto failure;
+    }
+
   expect (',');
 
   XSETFRAME (frame, f);
@@ -3942,18 +4000,6 @@
       expect (',');
     }
 
-  if (!x_create_x_image_and_pixmap (f, width, height, 0,
-				    &ximg, &img->pixmap)
-#ifndef HAVE_NS
-      || !x_create_x_image_and_pixmap (f, width, height, 1,
-				       &mask_img, &img->mask)
-#endif
-      )
-    {
-      image_error ("Out of memory (%s)", img->spec, Qnil);
-      goto error;
-    }
-
   for (y = 0; y < height; y++)
     {
       expect (XPM_TK_STRING);
@@ -5518,8 +5564,8 @@
 struct png_memory_storage
 {
   unsigned char *bytes;		/* The data       */
-  size_t len;			/* How big is it? */
-  int index;			/* Where are we?  */
+  ptrdiff_t len;		/* How big is it? */
+  ptrdiff_t index;		/* Where are we?  */
 };

@@ -5563,7 +5609,8 @@
 {
   Lisp_Object file, specified_file;
   Lisp_Object specified_data;
-  int x, y, i;
+  int x, y;
+  ptrdiff_t i;
   XImagePtr ximg, mask_img = NULL;
   png_struct *png_ptr = NULL;
   png_info *info_ptr = NULL, *end_info = NULL;
@@ -5683,11 +5730,19 @@
   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))
+  if (! (width <= INT_MAX && height <= INT_MAX
+	 && check_image_size (f, width, height)))
     {
       image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
       goto error;
     }
+
+  /* Create the X image and pixmap now, so that the work below can be
+     omitted if the image is too large for X.  */
+  if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg,
+				    &img->pixmap))
+    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))
@@ -5776,7 +5831,10 @@
   row_bytes = fn_png_get_rowbytes (png_ptr, info_ptr);
 
   /* Allocate memory for the image.  */
-  pixels = (png_byte *) xmalloc (row_bytes * height * sizeof *pixels);
+  if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *rows < height
+      || min (PTRDIFF_MAX, SIZE_MAX) / sizeof *pixels / height < row_bytes)
+    memory_full (SIZE_MAX);
+  pixels = (png_byte *) xmalloc (sizeof *pixels * row_bytes * height);
   rows = (png_byte **) xmalloc (height * sizeof *rows);
   for (i = 0; i < height; ++i)
     rows[i] = pixels + i * row_bytes;
@@ -5790,11 +5848,6 @@
       fp = NULL;
     }
 
-  /* Create the X image and pixmap.  */
-  if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg,
-				    &img->pixmap))
-    goto error;
-
   /* Create an image and pixmap serving as mask if the PNG image
      contains an alpha channel.  */
   if (channels == 4
@@ -6192,7 +6245,7 @@
   src = (struct jpeg_stdio_mgr *) cinfo->src;
   if (!src->finished)
     {
-      size_t bytes;
+      ptrdiff_t bytes;
 
       bytes = fread (src->buffer, 1, JPEG_STDIO_BUFFER_SIZE, src->file);
       if (bytes > 0)
@@ -6602,34 +6655,33 @@
 typedef struct
 {
   unsigned char *bytes;
-  size_t len;
-  int index;
+  ptrdiff_t len;
+  ptrdiff_t index;
 }
 tiff_memory_source;
 
-static size_t
+static tsize_t
 tiff_read_from_memory (thandle_t data, tdata_t buf, tsize_t size)
 {
   tiff_memory_source *src = (tiff_memory_source *) data;
 
-  if (size > src->len - src->index)
-    return (size_t) -1;
+  size = min (size, src->len - src->index);
   memcpy (buf, src->bytes + src->index, size);
   src->index += size;
   return size;
 }
 
-static size_t
+static tsize_t
 tiff_write_from_memory (thandle_t data, tdata_t buf, tsize_t size)
 {
-  return (size_t) -1;
+  return -1;
 }
 
 static toff_t
 tiff_seek_in_memory (thandle_t data, toff_t off, int whence)
 {
   tiff_memory_source *src = (tiff_memory_source *) data;
-  int idx;
+  ptrdiff_t idx;
 
   switch (whence)
     {
@@ -6765,8 +6817,8 @@
       memsrc.index = 0;
 
       tiff = fn_TIFFClientOpen ("memory_source", "r", (thandle_t)&memsrc,
-				(TIFFReadWriteProc) tiff_read_from_memory,
-				(TIFFReadWriteProc) tiff_write_from_memory,
+				tiff_read_from_memory,
+				tiff_write_from_memory,
 				tiff_seek_in_memory,
 				tiff_close_memory,
 				tiff_size_of_memory,
@@ -6805,7 +6857,16 @@
       return 0;
     }
 
-  buf = (uint32 *) xmalloc (width * height * sizeof *buf);
+  /* Create the X image and pixmap.  */
+  if (! (height <= min (PTRDIFF_MAX, SIZE_MAX) / sizeof *buf / width
+	 && x_create_x_image_and_pixmap (f, width, height, 0,
+					 &ximg, &img->pixmap)))
+    {
+      fn_TIFFClose (tiff);
+      return 0;
+    }
+
+  buf = (uint32 *) xmalloc (sizeof *buf * width * height);
 
   rc = fn_TIFFReadRGBAImage (tiff, width, height, buf, 0);
 
@@ -6826,13 +6887,6 @@
       return 0;
     }
 
-  /* Create the X image and pixmap.  */
-  if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
-    {
-      xfree (buf);
-      return 0;
-    }
-
   /* Initialize the color table.  */
   init_color_table ();
 
@@ -7034,8 +7088,8 @@
 typedef struct
 {
   unsigned char *bytes;
-  size_t len;
-  int index;
+  ptrdiff_t len;
+  ptrdiff_t index;
 }
 gif_memory_source;
 
@@ -7668,7 +7722,8 @@
   height = MagickGetImageHeight (image_wand);
   width = MagickGetImageWidth (image_wand);
 
-  if (! check_image_size (f, width, height))
+  if (! (width <= INT_MAX && height <= INT_MAX
+	 && check_image_size (f, width, height)))
     {
       image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
       goto imagemagick_error;
@@ -7872,7 +7927,7 @@
   size_t numf = 0;
   ExceptionInfo ex;
   char **imtypes = GetMagickList ("*", &numf, &ex);
-  int i;
+  size_t i;
   Lisp_Object Qimagemagicktype;
   for (i = 0; i < numf; i++)
     {
@@ -8426,12 +8481,15 @@
   /* Create the pixmap.  */
   xassert (img->pixmap == NO_PIXMAP);
 
-  /* Only W32 version did BLOCK_INPUT here.  ++kfs */
-  BLOCK_INPUT;
-  img->pixmap = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
-			       img->width, img->height,
-			       DefaultDepthOfScreen (FRAME_X_SCREEN (f)));
-  UNBLOCK_INPUT;
+  if (x_check_image_size (0, img->width, img->height))
+    {
+      /* Only W32 version did BLOCK_INPUT here.  ++kfs */
+      BLOCK_INPUT;
+      img->pixmap = XCreatePixmap (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+				   img->width, img->height,
+				   DefaultDepthOfScreen (FRAME_X_SCREEN (f)));
+      UNBLOCK_INPUT;
+    }
 
   if (!img->pixmap)
     {

=== modified file 'src/keyboard.c'
--- src/keyboard.c	2011-07-02 23:40:04 +0000
+++ src/keyboard.c	2011-07-07 17:55:38 +0000
@@ -210,8 +210,8 @@
 /* Last size recorded for a current buffer which is not a minibuffer.  */
 static EMACS_INT last_non_minibuf_size;
 
-/* Total number of times read_char has returned, modulo SIZE_MAX + 1.  */
-size_t num_input_events;
+/* Total number of times read_char has returned, modulo UINTMAX_MAX + 1.  */
+uintmax_t num_input_events;
 
 /* Value of num_nonmacro_input_events as of last auto save.  */

=== modified file 'src/keyboard.h'
--- src/keyboard.h	2011-06-23 06:31:41 +0000
+++ src/keyboard.h	2011-07-07 17:55:38 +0000
@@ -191,8 +191,8 @@
 /* A list of all kboard objects, linked through next_kboard.  */
 extern KBOARD *all_kboards;
 
-/* Total number of times read_char has returned, modulo SIZE_MAX + 1.  */
-extern size_t num_input_events;
+/* Total number of times read_char has returned, modulo UINTMAX_MAX + 1.  */
+extern uintmax_t num_input_events;
 
 /* Nonzero means polling for input is temporarily suppressed.  */
 extern int poll_suppress_count;

=== modified file 'src/lisp.h'
--- src/lisp.h	2011-07-14 07:27:40 +0000
+++ src/lisp.h	2011-07-14 07:50:51 +0000
@@ -61,6 +61,23 @@
 # define EMACS_UINT unsigned EMACS_INT
 #endif
 
+/* printmax_t and uprintmax_t are types for printing large integers.
+   These are the widest integers that are supported for printing.
+   pMd etc. are conversions for printing them.
+   On C99 hosts, there's no problem, as even the widest integers work.
+   Fall back on EMACS_INT on pre-C99 hosts.  */
+#ifdef PRIdMAX
+typedef intmax_t printmax_t;
+typedef uintmax_t uprintmax_t;
+# define pMd PRIdMAX
+# define pMu PRIuMAX
+#else
+typedef EMACS_INT printmax_t;
+typedef EMACS_UINT uprintmax_t;
+# define pMd pI"d"
+# define pMu pI"u"
+#endif
+
 /* Use pD to format ptrdiff_t values, which suffice for indexes into
    buffers and strings.  Emacs never allocates objects larger than
    PTRDIFF_MAX bytes, as they cause problems with pointer subtraction.
@@ -833,7 +850,7 @@
    <http://debbugs.gnu.org/cgi/bugreport.cgi?bug=8546>.  */
 struct vectorlike_header
   {
-    EMACS_UINT size;
+    EMACS_INT size;
 
     /* Pointer to the next vector-like object.  It is generally a buffer or a
        Lisp_Vector alias, so for convenience it is a union instead of a
@@ -1028,7 +1045,7 @@
 
 struct Lisp_Subr
   {
-    EMACS_UINT size;
+    EMACS_INT size;
     union {
       Lisp_Object (*a0) (void);
       Lisp_Object (*a1) (Lisp_Object);
@@ -2540,6 +2557,7 @@
 extern Lisp_Object Qcursor_in_echo_area;
 extern Lisp_Object Qstring_lessp;
 extern Lisp_Object QCsize, QCtest, QCweakness, Qequal, Qeq, Qeql;
+EMACS_UINT hash_string (char const *, ptrdiff_t);
 EMACS_UINT sxhash (Lisp_Object, int);
 Lisp_Object make_hash_table (Lisp_Object, Lisp_Object, Lisp_Object,
                              Lisp_Object, Lisp_Object, Lisp_Object,
@@ -2868,7 +2886,8 @@
 extern void syms_of_print (void);
 
 /* Defined in doprnt.c */
-extern size_t doprnt (char *, size_t, const char *, const char *, va_list);
+extern ptrdiff_t doprnt (char *, ptrdiff_t, const char *, const char *,
+			 va_list);
 
 /* Defined in lread.c.  */
 extern Lisp_Object Qvariable_documentation, Qstandard_input;

=== modified file 'src/lread.c'
--- src/lread.c	2011-07-10 08:20:10 +0000
+++ src/lread.c	2011-07-11 06:05:57 +0000
@@ -3647,8 +3647,6 @@
 
 static size_t oblookup_last_bucket_number;
 
-static size_t hash_string (const char *ptr, size_t len);
-
 /* Get an error if OBARRAY is not an obarray.
    If it is one, return it.  */
 
@@ -3891,23 +3889,6 @@
   XSETINT (tem, hash);
   return tem;
 }
-
-static size_t
-hash_string (const char *ptr, size_t len)
-{
-  register const char *p = ptr;
-  register const char *end = p + len;
-  register unsigned char c;
-  register size_t hash = 0;
-
-  while (p != end)
-    {
-      c = *p++;
-      if (c >= 0140) c -= 40;
-      hash = (hash << 3) + (hash >> (CHAR_BIT * sizeof hash - 4)) + c;
-    }
-  return hash;
-}
 
 void
 map_obarray (Lisp_Object obarray, void (*fn) (Lisp_Object, Lisp_Object), Lisp_Object arg)

=== modified file 'src/xdisp.c'
--- src/xdisp.c	2011-07-12 03:04:06 +0000
+++ src/xdisp.c	2011-07-12 17:38:05 +0000
@@ -8067,7 +8067,7 @@
       if (nlflag)
 	{
 	  EMACS_INT this_bol, this_bol_byte, prev_bol, prev_bol_byte;
-	  intmax_t dups;
+	  printmax_t dups;
 	  insert_1 ("\n", 1, 1, 0, 0);
 
 	  scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
@@ -8091,12 +8091,12 @@
 		  if (dups > 1)
 		    {
 		      char dupstr[sizeof " [ times]"
-				  + INT_STRLEN_BOUND (intmax_t)];
+				  + INT_STRLEN_BOUND (printmax_t)];
 		      int duplen;
 
 		      /* If you change this format, don't forget to also
 			 change message_log_check_duplicate.  */
-		      sprintf (dupstr, " [%"PRIdMAX" times]", dups);
+		      sprintf (dupstr, " [%"pMd" times]", dups);
 		      duplen = strlen (dupstr);
 		      TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
 		      insert_1 (dupstr, duplen, 1, 0, 1);
@@ -8489,7 +8489,7 @@
 	{
 	  if (m)
 	    {
-	      size_t len;
+	      ptrdiff_t len;
 
 	      len = doprnt (FRAME_MESSAGE_BUF (f),
 			    FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, ap);

=== modified file 'src/xfaces.c'
--- src/xfaces.c	2011-07-10 08:20:10 +0000
+++ src/xfaces.c	2011-07-12 17:34:59 +0000
@@ -940,11 +940,13 @@
 	    }
 	}
 
-      if (NATNUMP (width) && NATNUMP (height) && STRINGP (data))
+      if (STRINGP (data)
+	  && INTEGERP (width) && 0 < XINT (width)
+	  && INTEGERP (height) && 0 < XINT (height))
 	{
-	  int bytes_per_row = ((XFASTINT (width) + BITS_PER_CHAR - 1)
-			       / BITS_PER_CHAR);
-	  if (SBYTES (data) >= bytes_per_row * XINT (height))
+	  EMACS_INT bytes_per_row = ((XINT (width) + BITS_PER_CHAR - 1)
+				     / BITS_PER_CHAR);
+	  if (XINT (height) <= SBYTES (data) / bytes_per_row)
 	    pixmap_p = 1;
 	}
     }

=== modified file 'src/xselect.c'
--- src/xselect.c	2011-07-13 01:48:43 +0000
+++ src/xselect.c	2011-07-13 03:45:56 +0000
@@ -2381,7 +2381,7 @@
 {
   Atom x_atom;
   struct frame *f = check_x_frame (frame);
-  size_t i;
+  ptrdiff_t i;
   struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);

@@ -2402,6 +2402,9 @@
 
   if (dpyinfo->x_dnd_atoms_length == dpyinfo->x_dnd_atoms_size)
     {
+      if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *dpyinfo->x_dnd_atoms / 2
+	  < dpyinfo->x_dnd_atoms_size)
+	memory_full (SIZE_MAX);
       dpyinfo->x_dnd_atoms_size *= 2;
       dpyinfo->x_dnd_atoms = xrealloc (dpyinfo->x_dnd_atoms,
                                        sizeof (*dpyinfo->x_dnd_atoms)
@@ -2424,7 +2427,7 @@
   int x, y;
   unsigned char *data = (unsigned char *) event->data.b;
   int idata[5];
-  size_t i;
+  ptrdiff_t i;
 
   for (i = 0; i < dpyinfo->x_dnd_atoms_length; ++i)
     if (dpyinfo->x_dnd_atoms[i] == event->message_type) break;

=== modified file 'src/xterm.h'
--- src/xterm.h	2011-06-22 06:16:16 +0000
+++ src/xterm.h	2011-07-07 02:24:56 +0000
@@ -326,8 +326,8 @@
 
   /* Atoms that are drag and drop atoms */
   Atom *x_dnd_atoms;
-  size_t x_dnd_atoms_size;
-  size_t x_dnd_atoms_length;
+  ptrdiff_t x_dnd_atoms_size;
+  ptrdiff_t x_dnd_atoms_length;
 
   /* Extended window manager hints, Atoms supported by the window manager and
      atoms for settig the window type.  */

# Begin bundle