]> code.delx.au - gnu-emacs/commitdiff
Adjust in response to jan.h.d's comments.
authorPaul Eggert <eggert@cs.ucla.edu>
Fri, 5 Aug 2011 02:15:35 +0000 (19:15 -0700)
committerPaul Eggert <eggert@cs.ucla.edu>
Fri, 5 Aug 2011 02:15:35 +0000 (19:15 -0700)
See, for example <http://debbugs.gnu.org/cgi/bugreport.cgi?bug=9196#26>.

40 files changed:
src/ChangeLog
src/alloc.c
src/bidi.c
src/buffer.c
src/callproc.c
src/ccl.c
src/character.c
src/charset.c
src/cmds.c
src/composite.c
src/composite.h
src/dispextern.h
src/dispnew.c
src/doc.c
src/emacs.c
src/eval.c
src/fns.c
src/ftfont.c
src/gtkutil.c
src/image.c
src/indent.c
src/lisp.h
src/minibuf.c
src/nsterm.m
src/process.c
src/region-cache.c
src/region-cache.h
src/scroll.c
src/search.c
src/term.c
src/termcap.c
src/tparam.c
src/xdisp.c
src/xfaces.c
src/xfns.c
src/xgselect.c
src/xrdb.c
src/xselect.c
src/xsmfns.c
src/xterm.c

index a88e2e8e3cf7af194d35c6402995f1aa69e589eb..b525d83e2888e2faf5e17b2eea28e735ac896eff 100644 (file)
@@ -1,7 +1,48 @@
-2011-07-29  Paul Eggert  <eggert@cs.ucla.edu>
+2011-08-05  Paul Eggert  <eggert@cs.ucla.edu>
 
        Integer and memory overflow issues.
 
+       * charset.c (charset_table_size)
+       (struct charset_sort_data.priority): Now ptrdiff_t.
+       (charset_compare): Don't overflow if priorities differ greatly.
+       (Fsort_charsets): Don't assume list length fits in int.
+       Check for size-calculation overflow when allocating sort data.
+       (syms_of_charset): Allocate an initial charset table that is
+       just under 64 KiB, to avoid problems with glibc malloc and mmap.
+
+       * cmds.c (internal_self_insert): Check for size-calculation overflow.
+
+       * composite.h (struct composition.glyph_len): Now int, not unsigned.
+       The actual value is always <= INT_MAX, and leaving it unsigned made
+       overflow checking harder.
+
+       * dispextern.h (struct glyph_matrix.rows_allocated)
+       (struct face_cache.size): Now ptrdiff_t, for convenience in use
+       with xpalloc.  The values are still always <= INT_MAX.
+
+       * indent.c (compute_motion): Adjust to region_cache_forward sig change.
+
+       * lisp.h (xnmalloc, xnrealloc, xpalloc): New decls.
+       (SAFE_NALLOCA): New macro.
+
+       * region-cache.c (struct boundary.pos, find_cache_boundary)
+       (move_cache_gap, insert_cache_boundary, delete_cache_boundaries)
+       (set_cache_region, invalidate_region_cache)
+       (revalidate_region_cache, know_region_cache, region_cache_forward)
+       (region_cache_backward, pp_cache):
+       Use ptrdiff_t, not EMACS_INT, since either will do.  This is needed
+       so that ptrdiff_t * can be passed to xpalloc.
+       (struct region_cache): Similarly, for gap_start, gap_len, cache_len,
+       beg_unchanged, end_unchanged, buffer_beg, buffer_end members.
+       (pp_cache): Don't assume cache_len fits in int.
+       * region-cache.h: Adjust extern decls to match.
+
+       * search.c (scan_buffer, Freplace_match): Use ptrdiff_t, not
+       EMACS_INT, since either will do, for xpalloc.
+
+       * alloc.c: Include verify.h, and check that int fits in ptrdiff_t.
+       (xnmalloc, xnrealloc, xpalloc): New functions.
+
        * bidi.c (bidi_shelve_header_size): New constant.
        (bidi_cache_ensure_space, bidi_shelve_cache): Use it.
        (bidi_cache_ensure_space): Avoid integer overflow when allocating.
        (overlay_strings):
        Don't update size of array until after memory allocation succeeds,
        because xmalloc/xrealloc may not return.
+       (struct sortstrlist.bytes): Now ptrdiff_t, as EMACS_INT doesn't help
+       now that we have proper integer overflow checking.
+       (record_overlay_string, overlay_strings): Catch overflows when
+       calculating size of overlay_str_buf.
 
-       * callproc.c (child_setup): Don't assume strlen fits in int.
+       * callproc.c (Fcall_process): Check for size overflow when
+       calculating size of args2.
+       (child_setup): Avoid overflow by using size_t rather than ptrdiff_t.
+       Normally we prefer signed values, but sticking with ptrdiff_t would
+       require adding more-complicated checks.
 
        * ccl.c (Fccl_execute_on_string): Check for memory overflow.
        Use ptrdiff_t rather than EMACS_INT where ptrdiff_t will do.
        Redo buffer-overflow calculations to avoid integer overflow.
+       Add a FIXME comment where memory seems to be over-allocated.
 
        * character.c (Fstring): Check for size-calculation overflow.
 
        Don't assume message length fits in int.
        (Fformat): Use ptrdiff_t, not EMACS_INT, where ptrdiff_t will do.
 
-       * emacs.c (main, sort_args): Check for size-calculation overflow.
+       * emacs.c (main): Do not reallocate argv, since there is a null at
+       the end that can be overwritten, and this way there's no need to
+       worry about size-calculation overflow.
+       (sort_args): Check for size-calculation overflow.
 
        * eval.c (init_eval_once, grow_specpdl): Don't update size until
        alloc succeeds.
        * macros.c (Fstart_kbd_macro): Don't update size until alloc done.
        (store_kbd_macro_char): Reorder multiplicands to avoid overflow.
 
-       * minibuf.c (read_minibuf_noninteractive): Don't leak memory
-       on memory overflow.
-
        * nsterm.h (struct ns_color_table.size, struct ns_color_table.avail):
        Now ptrdiff_t, not int.
        * nsterm.m (ns_index_color): Use ptrdiff_t, not int, for table indexes.
        Don't update size until alloc done.
        Redo size calculations to avoid overflow.
        Check for size calculation overflow.
+       (main) [DEBUG]: Fix typo in invoking tparam1.
 
        * xdisp.c (store_mode_line_noprop_char, x_consider_frame_title):
        Use ptrdiff_t, not int, for sizes.
        (store_mode_line_noprop_char): Don't update size until alloc done.
 
-       * xfaces.c (Finternal_make_lisp_face): Use ptrdiff_t, not int, for
-       sizes.  Check for size calculation overflow.
-       (cache_face): Do not overflow in size calculation.
+       * xfaces.c (lface_id_to_name_size, Finternal_make_lisp_face):
+       Use ptrdiff_t, not int, for sizes.
+       (Finternal_make_lisp_face, cache_face):
+       Check for size calculation overflow.
+       (cache_face): Treat size calculation overflows as if they were
+       memory exhaustion (the usual treatment), rather than aborting.
 
        * xfns.c (x_encode_text, x_set_name_internal)
        (Fx_change_window_property): Use ptrdiff_t, not int, to count
        sizes, since they can exceed INT_MAX in size.  Check for size
        calculation overflow.
 
-       * xgselect.c (xg_select): Check for size calculation overflow.
+       * xgselect.c (gfds_size): Now ptrdiff_t, for convenience with xpalloc.
+       (xg_select): Check for size calculation overflow.
        Don't update size until alloc done.
 
-       * xrdb.c (magic_file_p): Plug memory leak on size overflow.
-       (get_environ_db): Don't assume path length fits in int,
+       * xrdb.c (get_environ_db): Don't assume path length fits in int,
        as sprintf is limited to int lengths.
 
        * xselect.c (X_LONG_SIZE, X_USHRT_MAX, X_ULONG_MAX): New macros.
 
        * xsmfns.c (smc_save_yourself_CB): Check for size calc overflow.
 
-       * xterm.c (x_color_cells, handle_one_xevent, x_term_init):
-       Check for size calculation overflow.
+       * xterm.c (x_color_cells, x_send_scrollbar_event, handle_one_xevent)
+       (x_term_init): Check for size calculation overflow.
        (x_color_cells): Don't store size until memory allocation succeeds.
        (handle_one_xevent): Use ptrdiff_t, not int, for byte counts.
+       Don't assume alloca size is less than MAX_ALLOCA.
        (x_term_init): Don't assume length fits in int (sprintf is limited
        to int size).
 
index b96fc1f06424610d931b4d078f2b6821dfe63400..a1af0df11f0ecd4e94ebbf1b40c7a6f08feef8fb 100644 (file)
@@ -46,6 +46,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include "syssignal.h"
 #include "termhooks.h"         /* For struct terminal.  */
 #include <setjmp.h>
+#include <verify.h>
 
 /* GC_MALLOC_CHECK defined means perform validity checks of malloc'd
    memory.  Can do this only if using gmalloc.c.  */
@@ -731,6 +732,93 @@ xfree (POINTER_TYPE *block)
 }
 
 
+/* Other parts of Emacs pass large int values to allocator functions
+   expecting ptrdiff_t.  This is portable in practice, but check it to
+   be safe.  */
+verify (INT_MAX <= PTRDIFF_MAX);
+
+
+/* Allocate an array of NITEMS items, each of size ITEM_SIZE.
+   Signal an error on memory exhaustion, and block interrupt input.  */
+
+void *
+xnmalloc (ptrdiff_t nitems, ptrdiff_t item_size)
+{
+  xassert (0 <= nitems && 0 < item_size);
+  if (min (PTRDIFF_MAX, SIZE_MAX) / item_size < nitems)
+    memory_full (SIZE_MAX);
+  return xmalloc (nitems * item_size);
+}
+
+
+/* Reallocate an array PA to make it of NITEMS items, each of size ITEM_SIZE.
+   Signal an error on memory exhaustion, and block interrupt input.  */
+
+void *
+xnrealloc (void *pa, ptrdiff_t nitems, ptrdiff_t item_size)
+{
+  xassert (0 <= nitems && 0 < item_size);
+  if (min (PTRDIFF_MAX, SIZE_MAX) / item_size < nitems)
+    memory_full (SIZE_MAX);
+  return xrealloc (pa, nitems * item_size);
+}
+
+
+/* Grow PA, which points to an array of *NITEMS items, and return the
+   location of the reallocated array, updating *NITEMS to reflect its
+   new size.  The new array will contain at least NITEMS_INCR_MIN more
+   items, but will not contain more than NITEMS_MAX items total.
+   ITEM_SIZE is the size of each item, in bytes.
+
+   ITEM_SIZE and NITEMS_INCR_MIN must be positive.  *NITEMS must be
+   nonnegative.  If NITEMS_MAX is -1, it is treated as if it were
+   infinity.
+
+   If PA is null, then allocate a new array instead of reallocating
+   the old one.  Thus, to grow an array A without saving its old
+   contents, invoke xfree (A) immediately followed by xgrowalloc (0,
+   &NITEMS, ...).
+
+   Block interrupt input as needed.  If memory exhaustion occurs, set
+   *NITEMS to zero if PA is null, and signal an error (i.e., do not
+   return).  */
+
+void *
+xpalloc (void *pa, ptrdiff_t *nitems, ptrdiff_t nitems_incr_min,
+        ptrdiff_t nitems_max, ptrdiff_t item_size)
+{
+  /* The approximate size to use for initial small allocation
+     requests.  This is the largest "small" request for the GNU C
+     library malloc.  */
+  enum { DEFAULT_MXFAST = 64 * sizeof (size_t) / 4 };
+
+  /* If the array is tiny, grow it to about (but no greater than)
+     DEFAULT_MXFAST bytes.  Otherwise, grow it by about 50%.  */
+  ptrdiff_t n = *nitems;
+  ptrdiff_t tiny_max = DEFAULT_MXFAST / item_size - n;
+  ptrdiff_t half_again = n >> 1;
+  ptrdiff_t incr_estimate = max (tiny_max, half_again);
+
+  /* Adjust the increment according to three constraints: NITEMS_INCR_MIN,
+     NITEMS_MAX, and what the C language can represent safely.  */
+  ptrdiff_t C_language_max = min (PTRDIFF_MAX, SIZE_MAX) / item_size;
+  ptrdiff_t n_max = (0 <= nitems_max && nitems_max < C_language_max
+                    ? nitems_max : C_language_max);
+  ptrdiff_t nitems_incr_max = n_max - n;
+  ptrdiff_t incr = max (nitems_incr_min, min (incr_estimate, nitems_incr_max));
+
+  xassert (0 < item_size && 0 < nitems_incr_min && 0 <= n && -1 <= nitems_max);
+  if (! pa)
+    *nitems = 0;
+  if (nitems_incr_max < incr)
+    memory_full (SIZE_MAX);
+  n += incr;
+  pa = xrealloc (pa, n * item_size);
+  *nitems = n;
+  return pa;
+}
+
+
 /* Like strdup, but uses xmalloc.  */
 
 char *
index a1e5721f35001f13acc1ca48c642e392c4d5638a..27a6645dffd8c89ec285236f5c3de1d6e4547dcf 100644 (file)
@@ -478,8 +478,6 @@ bidi_cache_ensure_space (ptrdiff_t idx)
   /* Enlarge the cache as needed.  */
   if (idx >= bidi_cache_size)
     {
-      ptrdiff_t new_size;
-
       /* The bidi cache cannot be larger than the largest Lisp string
         or buffer.  */
       ptrdiff_t string_or_buffer_bound =
@@ -489,11 +487,10 @@ bidi_cache_ensure_space (ptrdiff_t idx)
       ptrdiff_t c_bound =
        (min (PTRDIFF_MAX, SIZE_MAX) - bidi_shelve_header_size) / elsz;
 
-      if (min (string_or_buffer_bound, c_bound) <= idx)
-       memory_full (SIZE_MAX);
-      new_size = idx - idx % BIDI_CACHE_CHUNK + BIDI_CACHE_CHUNK;
-      bidi_cache = (struct bidi_it *) xrealloc (bidi_cache, new_size * elsz);
-      bidi_cache_size = new_size;
+      bidi_cache =
+       xpalloc (bidi_cache, &bidi_cache_size,
+                max (BIDI_CACHE_CHUNK, idx - bidi_cache_size + 1),
+                min (string_or_buffer_bound, c_bound), elsz);
     }
 }
 
index cacc8a4133974da1fec5f07207f44576a10e010f..b61d083c3e6a11ca2d1def513c6702d52f382b8b 100644 (file)
@@ -2568,13 +2568,10 @@ overlays_at (EMACS_INT pos, int extend, Lisp_Object **vec_ptr,
                 Either make it bigger, or don't store any more in it.  */
              if (extend)
                {
-                 if ((OVERLAY_COUNT_MAX - 4) / 2 < len)
-                   memory_full (SIZE_MAX);
-                 /* Make it work with an initial len == 0.  */
-                 len = len * 2 + 4;
-                 vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
+                 vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
+                                sizeof *vec);
                  *vec_ptr = vec;
-                 *len_ptr = len;
+                 len = *len_ptr;
                }
              else
                inhibit_storing = 1;
@@ -2611,13 +2608,10 @@ overlays_at (EMACS_INT pos, int extend, Lisp_Object **vec_ptr,
            {
              if (extend)
                {
-                 if ((OVERLAY_COUNT_MAX - 4) / 2 < len)
-                   memory_full (SIZE_MAX);
-                 /* Make it work with an initial len == 0.  */
-                 len = len * 2 + 4;
-                 vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
+                 vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
+                                sizeof *vec);
                  *vec_ptr = vec;
-                 *len_ptr = len;
+                 len = *len_ptr;
                }
              else
                inhibit_storing = 1;
@@ -2708,13 +2702,10 @@ overlays_in (EMACS_INT beg, EMACS_INT end, int extend,
                 Either make it bigger, or don't store any more in it.  */
              if (extend)
                {
-                 if ((OVERLAY_COUNT_MAX - 4) / 2 < len)
-                   memory_full (SIZE_MAX);
-                 /* Make it work with an initial len == 0.  */
-                 len = len * 2 + 4;
-                 vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
+                 vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
+                                sizeof *vec);
                  *vec_ptr = vec;
-                 *len_ptr = len;
+                 len = *len_ptr;
                }
              else
                inhibit_storing = 1;
@@ -2756,13 +2747,10 @@ overlays_in (EMACS_INT beg, EMACS_INT end, int extend,
            {
              if (extend)
                {
-                 if ((OVERLAY_COUNT_MAX - 4) / 2 < len)
-                   memory_full (SIZE_MAX);
-                 /* Make it work with an initial len == 0.  */
-                 len = len * 2 + 4;
-                 vec = (Lisp_Object *) xrealloc (vec, len * sizeof (Lisp_Object));
+                 vec = xpalloc (vec, len_ptr, 1, OVERLAY_COUNT_MAX,
+                                sizeof *vec);
                  *vec_ptr = vec;
-                 *len_ptr = len;
+                 len = *len_ptr;
                }
              else
                inhibit_storing = 1;
@@ -2944,7 +2932,7 @@ struct sortstrlist
   struct sortstr *buf; /* An array that expands as needed; never freed.  */
   ptrdiff_t size;      /* Allocated length of that array.  */
   ptrdiff_t used;      /* How much of the array is currently in use.  */
-  EMACS_INT bytes;             /* Total length of the strings in buf.  */
+  ptrdiff_t bytes;     /* Total length of the strings in buf.  */
 };
 
 /* Buffers for storing information about the overlays touching a given
@@ -2977,14 +2965,7 @@ record_overlay_string (struct sortstrlist *ssl, Lisp_Object str,
   EMACS_INT nbytes;
 
   if (ssl->used == ssl->size)
-    {
-      ptrdiff_t ssl_size = 0 < ssl->size ? ssl->size * 2 : 5;
-      if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (struct sortstr) < ssl_size)
-       memory_full (SIZE_MAX);
-      ssl->buf = ((struct sortstr *)
-                 xrealloc (ssl->buf, ssl_size * sizeof (struct sortstr)));
-      ssl->size = ssl_size;
-    }
+    ssl->buf = xpalloc (ssl->buf, &ssl->size, 5, -1, sizeof *ssl->buf);
   ssl->buf[ssl->used].string = str;
   ssl->buf[ssl->used].string2 = str2;
   ssl->buf[ssl->used].size = size;
@@ -2999,6 +2980,8 @@ record_overlay_string (struct sortstrlist *ssl, Lisp_Object str,
   else
     nbytes = SBYTES (str);
 
+  if (INT_ADD_OVERFLOW (ssl->bytes, nbytes))
+    memory_full (SIZE_MAX);
   ssl->bytes += nbytes;
 
   if (STRINGP (str2))
@@ -3011,6 +2994,8 @@ record_overlay_string (struct sortstrlist *ssl, Lisp_Object str,
       else
        nbytes = SBYTES (str2);
 
+      if (INT_ADD_OVERFLOW (ssl->bytes, nbytes))
+       memory_full (SIZE_MAX);
       ssl->bytes += nbytes;
     }
 }
@@ -3104,14 +3089,15 @@ overlay_strings (EMACS_INT pos, struct window *w, unsigned char **pstr)
       Lisp_Object tem;
       EMACS_INT i;
       unsigned char *p;
-      EMACS_INT total = overlay_heads.bytes + overlay_tails.bytes;
+      ptrdiff_t total;
 
+      if (INT_ADD_OVERFLOW (overlay_heads.bytes, overlay_tails.bytes))
+       memory_full (SIZE_MAX);
+      total = overlay_heads.bytes + overlay_tails.bytes;
       if (total > overlay_str_len)
-       {
-         overlay_str_buf = (unsigned char *)xrealloc (overlay_str_buf,
-                                                      total);
-         overlay_str_len = total;
-       }
+       overlay_str_buf = xpalloc (overlay_str_buf, &overlay_str_len,
+                                  total - overlay_str_len, -1, 1);
+
       p = overlay_str_buf;
       for (i = overlay_tails.used; --i >= 0;)
        {
index 993d943e158c4144ae7dc15504196bcbf3071faf..4f6d363d5e20a7766c5ba398756ddc9115b35be2 100644 (file)
@@ -252,7 +252,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS)  */)
          val = Qraw_text;
        else
          {
-           SAFE_ALLOCA (args2, Lisp_Object *, (nargs + 1) * sizeof *args2);
+           SAFE_NALLOCA (args2, 1, nargs + 1);
            args2[0] = Qcall_process;
            for (i = 0; i < nargs; i++) args2[i + 1] = args[i];
            coding_systems = Ffind_operation_coding_system (nargs + 1, args2);
@@ -720,7 +720,7 @@ usage: (call-process PROGRAM &optional INFILE BUFFER DISPLAY &rest ARGS)  */)
            {
              ptrdiff_t i;
 
-             SAFE_ALLOCA (args2, Lisp_Object *, (nargs + 1) * sizeof *args2);
+             SAFE_NALLOCA (args2, 1, nargs + 1);
              args2[0] = Qcall_process;
              for (i = 0; i < nargs; i++) args2[i + 1] = args[i];
              coding_systems
@@ -1018,7 +1018,7 @@ usage: (call-process-region START END PROGRAM &optional DELETE BUFFER DISPLAY &r
   else
     {
       USE_SAFE_ALLOCA;
-      SAFE_ALLOCA (args2, Lisp_Object *, (nargs + 1) * sizeof *args2);
+      SAFE_NALLOCA (args2, 1, nargs + 1);
       args2[0] = Qcall_process_region;
       for (i = 0; i < nargs; i++) args2[i + 1] = args[i];
       coding_systems = Ffind_operation_coding_system (nargs + 1, args2);
@@ -1147,11 +1147,9 @@ child_setup (int in, int out, int err, register char **new_argv, int set_pgrp, L
      cleaned up in the usual way. */
   {
     register char *temp;
-    register ptrdiff_t i;
+    size_t i; /* size_t, because ptrdiff_t might overflow here!  */
 
     i = SBYTES (current_dir);
-    if (min (PTRDIFF_MAX, SIZE_MAX) - 6 < i)
-      memory_full (SIZE_MAX);
 #ifdef MSDOS
     /* MSDOS must have all environment variables malloc'ed, because
        low-level libc functions that launch subsidiary processes rely
index 0a9b3d907084329d4788419d44a26a03d4e00995..dc0adae68773669cc06ae3cca4e6327c7136a0ad 100644 (file)
--- a/src/ccl.c
+++ b/src/ccl.c
@@ -2067,6 +2067,7 @@ usage: (ccl-execute-on-string CCL-PROGRAM STATUS STRING &optional CONTINUE UNIBY
 #define CCL_EXECUTE_BUF_SIZE 1024
   int source[CCL_EXECUTE_BUF_SIZE], destination[CCL_EXECUTE_BUF_SIZE];
   ptrdiff_t consumed_chars, consumed_bytes, produced_chars;
+  int buf_magnification;
 
   if (setup_ccl_program (&ccl, ccl_prog) < 0)
     error ("Invalid CCL program");
@@ -2093,9 +2094,9 @@ usage: (ccl-execute-on-string CCL-PROGRAM STATUS STRING &optional CONTINUE UNIBY
        ccl.ic = i;
     }
 
-  if (((min (PTRDIFF_MAX, SIZE_MAX) - 256)
-       / (ccl.buf_magnification ? ccl.buf_magnification : 1))
-      < str_bytes)
+  buf_magnification = ccl.buf_magnification ? ccl.buf_magnification : 1;
+
+  if ((min (PTRDIFF_MAX, SIZE_MAX) - 256) / buf_magnification < str_bytes)
     memory_full (SIZE_MAX);
   outbufsize = (ccl.buf_magnification
                ? str_bytes * ccl.buf_magnification + 256
@@ -2131,20 +2132,18 @@ usage: (ccl-execute-on-string CCL-PROGRAM STATUS STRING &optional CONTINUE UNIBY
          produced_chars += ccl.produced;
          if (NILP (unibyte_p))
            {
+             /* FIXME: Surely this should be buf_magnification instead.
+                MAX_MULTIBYTE_LENGTH overestimates the storage needed.  */
+             int magnification = MAX_MULTIBYTE_LENGTH;
+
              ptrdiff_t offset = outp - outbuf;
-             if ((outbufsize - offset) / MAX_MULTIBYTE_LENGTH < ccl.produced)
+             ptrdiff_t shortfall;
+             if (INT_MULTIPLY_OVERFLOW (ccl.produced, magnification))
+               memory_full (SIZE_MAX);
+             shortfall = ccl.produced * magnification - (outbufsize - offset);
+             if (0 < shortfall)
                {
-                 ptrdiff_t produced;
-                 if (((min (PTRDIFF_MAX, SIZE_MAX) - outbufsize)
-                      / MAX_MULTIBYTE_LENGTH)
-                     < ccl.produced)
-                   {
-                     xfree (outbuf);
-                     memory_full (SIZE_MAX);
-                   }
-                 produced = ccl.produced;
-                 outbufsize += MAX_MULTIBYTE_LENGTH * produced;
-                 outbuf = (unsigned char *) xrealloc (outbuf, outbufsize);
+                 outbuf = xpalloc (outbuf, &outbufsize, shortfall, -1, 1);
                  outp = outbuf + offset;
                }
              for (j = 0; j < ccl.produced; j++)
@@ -2153,15 +2152,10 @@ usage: (ccl-execute-on-string CCL-PROGRAM STATUS STRING &optional CONTINUE UNIBY
          else
            {
              ptrdiff_t offset = outp - outbuf;
-             if (outbufsize - offset < ccl.produced)
+             ptrdiff_t shortfall = ccl.produced - (outbufsize - offset);
+             if (0 < shortfall)
                {
-                 if (min (PTRDIFF_MAX, SIZE_MAX) - outbufsize < ccl.produced)
-                   {
-                     xfree (outbuf);
-                     memory_full (SIZE_MAX);
-                   }
-                 outbufsize += ccl.produced;
-                 outbuf = (unsigned char *) xrealloc (outbuf, outbufsize);
+                 outbuf = xpalloc (outbuf, &outbufsize, shortfall, -1, 1);
                  outp = outbuf + offset;
                }
              for (j = 0; j < ccl.produced; j++)
index 50b5b252871fb316bbd43f2d99b81cadf1eb372a..fb9b8a9b93e9f18942654f8ac9d151bc4d1550d9 100644 (file)
@@ -902,9 +902,7 @@ usage: (string &rest CHARACTERS)  */)
   Lisp_Object str;
   USE_SAFE_ALLOCA;
 
-  if (min (PTRDIFF_MAX, SIZE_MAX) / MAX_MULTIBYTE_LENGTH < n)
-    memory_full (SIZE_MAX);
-  SAFE_ALLOCA (buf, unsigned char *, MAX_MULTIBYTE_LENGTH * n);
+  SAFE_NALLOCA (buf, MAX_MULTIBYTE_LENGTH, n);
   p = buf;
 
   for (i = 0; i < n; i++)
index 852aeb19bcb17cf57ccd7113dde523548d86bdeb..6967b9df61157344d9ae5acf36a701f86c7f2854 100644 (file)
@@ -61,7 +61,7 @@ Lisp_Object Vcharset_hash_table;
 /* Table of struct charset.  */
 struct charset *charset_table;
 
-static int charset_table_size;
+static ptrdiff_t charset_table_size;
 static int charset_table_used;
 
 Lisp_Object Qcharsetp;
@@ -1150,28 +1150,25 @@ usage: (define-charset-internal ...)  */)
                                     hash_code);
       if (charset_table_used == charset_table_size)
        {
-         struct charset *new_table;
          /* Ensure that charset IDs fit into 'int' as well as into the
-            restriction imposed by fixnums, ptrdiff_t, and size_t.
-            Although the 'int' restriction could be removed, too much other
-            code would need altering; for example, the IDs are stuffed into
-            struct coding_system.charbuf[i] entries, which are 'int'.  */
-         int charset_table_size_max =
-           min (min (INT_MAX, MOST_POSITIVE_FIXNUM),
-                min (PTRDIFF_MAX, SIZE_MAX) / sizeof (struct charset));
-         if (charset_table_size_max - 16 < charset_table_size)
-           memory_full (SIZE_MAX);
-         new_table
-           = (struct charset *) xmalloc (sizeof (struct charset)
-                                         * (charset_table_size + 16));
-         memcpy (new_table, charset_table,
-                 sizeof (struct charset) * charset_table_size);
-         charset_table_size += 16;
+            restriction imposed by fixnums.  Although the 'int' restriction
+            could be removed, too much other code would need altering; for
+            example, the IDs are stuffed into struct
+            coding_system.charbuf[i] entries, which are 'int'.  */
+         int old_size = charset_table_size;
+         struct charset *new_table =
+           xpalloc (0, &charset_table_size, 1,
+                    min (INT_MAX, MOST_POSITIVE_FIXNUM),
+                    sizeof *charset_table);
+         memcpy (new_table, charset_table, old_size * sizeof *new_table);
          charset_table = new_table;
-         /* FIXME: Doesn't this leak memory?  The old charset_table
-            becomes unreachable.  If the memory leak is intentional,
-            a comment should be added to explain this.  If not, the
-            old charset_table should be freed, using xfree.  */
+         /* FIXME: Doesn't this leak memory?  The old charset_table becomes
+            unreachable.  It could be that this is intentional, because the
+            old charset table may be in a dumped emacs, and reallocating such
+            a table may not work.  If the memory leak is intentional, a
+            comment should be added to explain this.  If not, the old
+            charset_table should be freed, by passing it as the 1st argument
+            to xpalloc and removing the memcpy.  */
        }
       id = charset_table_used++;
       new_definition_p = 1;
@@ -2230,14 +2227,16 @@ struct charset_sort_data
 {
   Lisp_Object charset;
   int id;
-  int priority;
+  ptrdiff_t priority;
 };
 
 static int
 charset_compare (const void *d1, const void *d2)
 {
   const struct charset_sort_data *data1 = d1, *data2 = d2;
-  return (data1->priority - data2->priority);
+  if (data1->priority != data2->priority)
+    return data1->priority < data2->priority ? -1 : 1;
+  return 0;
 }
 
 DEFUN ("sort-charsets", Fsort_charsets, Ssort_charsets, 1, 1, 0,
@@ -2247,7 +2246,8 @@ See also `charset-priority-list' and `set-charset-priority'.  */)
      (Lisp_Object charsets)
 {
   Lisp_Object len = Flength (charsets);
-  int n = XFASTINT (len), i, j, done;
+  ptrdiff_t n = XFASTINT (len), i, j;
+  int done;
   Lisp_Object tail, elt, attrs;
   struct charset_sort_data *sort_data;
   int id, min_id = INT_MAX, max_id = INT_MIN;
@@ -2255,7 +2255,7 @@ See also `charset-priority-list' and `set-charset-priority'.  */)
 
   if (n == 0)
     return Qnil;
-  SAFE_ALLOCA (sort_data, struct charset_sort_data *, sizeof (*sort_data) * n);
+  SAFE_NALLOCA (sort_data, 1, n);
   for (tail = charsets, i = 0; CONSP (tail); tail = XCDR (tail), i++)
     {
       elt = XCAR (tail);
@@ -2330,6 +2330,17 @@ init_charset_once (void)
 void
 syms_of_charset (void)
 {
+  /* Allocate an initial charset table that is just under 64 KiB in size.
+     This should be large enough so that the charset table need not be
+     reallocated during an initial bootstrap.  Allocating anything larger than
+     64 KiB in an initial run may not work, because glibc malloc might use
+     mmap for larger allocations, and these don't work well across dumped
+     systems.  */
+  enum {
+    initial_malloc_max = (1 << 16) - 1,
+    charset_table_size_init = initial_malloc_max / sizeof (struct charset)
+  };
+
   DEFSYM (Qcharsetp, "charsetp");
 
   DEFSYM (Qascii, "ascii");
@@ -2362,8 +2373,9 @@ syms_of_charset (void)
     Vcharset_hash_table = Fmake_hash_table (2, args);
   }
 
-  charset_table = (struct charset *) xmalloc (sizeof (struct charset) * 128);
-  charset_table_size = 128;
+  charset_table = (struct charset *) xmalloc (sizeof (struct charset)
+                                             * charset_table_size_init);
+  charset_table_size = charset_table_size_init;
   charset_table_used = 0;
 
   defsubr (&Scharsetp);
index f49cfc221be995d291a6316b2fd7fab7487b5782..2feaf313f23263496c76196c34c7e6a0ca405b7f 100644 (file)
@@ -471,7 +471,7 @@ internal_self_insert (int c, EMACS_INT n)
     {
       USE_SAFE_ALLOCA;
       char *strn, *p;
-      SAFE_ALLOCA (strn, char *, n * len);
+      SAFE_NALLOCA (strn, len, n);
       for (p = strn; n > 0; n--, p += len)
        memcpy (p, str, len);
       insert_and_inherit (strn, p - strn);
index 4ae1d6ebb684fcd2465f67c3f54747cbde5cd97a..738fcd3774c00ff9e4b494614e10c35ec8d3122b 100644 (file)
@@ -186,13 +186,14 @@ get_composition_id (EMACS_INT charpos, EMACS_INT bytepos, EMACS_INT nchars,
   EMACS_INT i;
   int ch;
 
-  /* Maximum length of a string of glyphs.  XftGlyphExtents limits this
-     to INT_MAX, and Emacs may limit it further.  */
+  /* Maximum length of a string of glyphs.  XftGlyphExtents limits
+     this to INT_MAX, and Emacs limits it further.  Divide INT_MAX - 1
+     by 2 because x_produce_glyphs computes glyph_len * 2 + 1.  Divide
+     the size by MAX_MULTIBYTE_LENGTH because encode_terminal_code
+     multiplies glyph_len by MAX_MULTIBYTE_LENGTH.  */
   enum {
-    glyph_len_max =
-      min (INT_MAX,
-          (min (PTRDIFF_MAX, SIZE_MAX)
-           / max (MAX_MULTIBYTE_LENGTH, 2 * sizeof (short))))
+    GLYPH_LEN_MAX = min ((INT_MAX - 1) / 2,
+                        min (PTRDIFF_MAX, SIZE_MAX) / MAX_MULTIBYTE_LENGTH)
   };
 
   /* PROP should be
@@ -268,25 +269,9 @@ get_composition_id (EMACS_INT charpos, EMACS_INT bytepos, EMACS_INT nchars,
   /* This composition is a new one.  We must register it.  */
 
   /* Check if we have sufficient memory to store this information.  */
-  if (composition_table_size == 0)
-    {
-      composition_table
-       = (struct composition **) xmalloc (sizeof (composition_table[0]) * 256);
-      composition_table_size = 256;
-    }
-  else if (composition_table_size <= n_compositions)
-    {
-      if ((min (MOST_POSITIVE_FIXNUM,
-               min (PTRDIFF_MAX, SIZE_MAX) / sizeof composition_table[0])
-          - 256)
-         < composition_table_size)
-       memory_full (SIZE_MAX);
-      composition_table
-       = (struct composition **) xrealloc (composition_table,
-                                           sizeof (composition_table[0])
-                                           * (composition_table_size + 256));
-      composition_table_size += 256;
-    }
+  if (composition_table_size <= n_compositions)
+    composition_table = xpalloc (composition_table, &composition_table_size,
+                                1, -1, sizeof *composition_table);
 
   key_contents = XVECTOR (key)->contents;
 
@@ -340,7 +325,7 @@ get_composition_id (EMACS_INT charpos, EMACS_INT bytepos, EMACS_INT nchars,
               ? (ASIZE (key) + 1) / 2
               : ASIZE (key));
 
-  if (glyph_len_max < glyph_len)
+  if (GLYPH_LEN_MAX < glyph_len)
     memory_full (SIZE_MAX);
 
   /* Register the composition in composition_table.  */
@@ -349,7 +334,7 @@ get_composition_id (EMACS_INT charpos, EMACS_INT bytepos, EMACS_INT nchars,
   cmp->method = method;
   cmp->hash_index = hash_index;
   cmp->glyph_len = glyph_len;
-  cmp->offsets = (short *) xmalloc (sizeof (short) * glyph_len * 2);
+  cmp->offsets = xnmalloc (glyph_len, 2 * sizeof *cmp->offsets);
   cmp->font = NULL;
 
   if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
index c30c6832796a5f62d46e6555dc57aa7f029c156e..c57e2a0e9b354e46041ae63900b0f73e3a9afd57 100644 (file)
@@ -170,7 +170,7 @@ extern Lisp_Object composition_temp;
 
 struct composition {
   /* Number of glyphs of the composition components.  */
-  unsigned glyph_len;
+  int glyph_len;
 
   /* Width, ascent, and descent pixels of the composition.  */
   short pixel_width, ascent, descent;
index 70f426f95a60358e67b7f2575cb994f0581195c5..c43eeb556091ca38cd970177e3badc09b308333b 100644 (file)
@@ -625,7 +625,7 @@ struct glyph_matrix
   struct glyph_row *rows;
 
   /* Number of elements allocated for the vector rows above.  */
-  int rows_allocated;
+  ptrdiff_t rows_allocated;
 
   /* The number of rows used by the window if all lines were displayed
      with the smallest possible character height.  */
@@ -1708,7 +1708,8 @@ struct face_cache
   struct face **faces_by_id;
 
   /* The allocated size, and number of used slots of faces_by_id.  */
-  int size, used;
+  ptrdiff_t size;
+  int used;
 
   /* Flag indicating that attributes of the `menu' face have been
      changed.  */
index 4cc101d98bf7b9725b71c988dd0a9785dcb8683f..fde9be6bf5c21f0bdc7ff04d8b270e047849d2ef 100644 (file)
@@ -499,15 +499,12 @@ adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y
   /* Enlarge MATRIX->rows if necessary.  New rows are cleared.  */
   if (matrix->rows_allocated < dim.height)
     {
-      ptrdiff_t size;
-      if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (struct glyph_row) < dim.height)
-       memory_full (SIZE_MAX);
-      size = dim.height * sizeof (struct glyph_row);
+      int old_alloc = matrix->rows_allocated;
       new_rows = dim.height - matrix->rows_allocated;
-      matrix->rows = (struct glyph_row *) xrealloc (matrix->rows, size);
-      memset (matrix->rows + matrix->rows_allocated, 0,
-             new_rows * sizeof *matrix->rows);
-      matrix->rows_allocated = dim.height;
+      matrix->rows = xpalloc (matrix->rows, &matrix->rows_allocated,
+                             new_rows, INT_MAX, sizeof *matrix->rows);
+      memset (matrix->rows + old_alloc, 0,
+             (matrix->rows_allocated - old_alloc) * sizeof *matrix->rows);
     }
   else
     new_rows = 0;
@@ -576,15 +573,11 @@ adjust_glyph_matrix (struct window *w, struct glyph_matrix *matrix, int x, int y
          struct glyph_row *row = matrix->rows;
          struct glyph_row *end = row + matrix->rows_allocated;
 
-         if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (struct glyph) < dim.width)
-           memory_full (SIZE_MAX);
-
          while (row < end)
            {
              row->glyphs[LEFT_MARGIN_AREA]
-               = (struct glyph *) xrealloc (row->glyphs[LEFT_MARGIN_AREA],
-                                            (dim.width
-                                             * sizeof (struct glyph)));
+               = xnrealloc (row->glyphs[LEFT_MARGIN_AREA],
+                            dim.width, sizeof (struct glyph));
 
              /* The mode line never has marginal areas.  */
              if (row == matrix->rows + dim.height - 1
@@ -1404,20 +1397,18 @@ realloc_glyph_pool (struct glyph_pool *pool, struct dim matrix_dim)
               || matrix_dim.height != pool->nrows
               || matrix_dim.width != pool->ncolumns);
 
-  if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (struct glyph) / matrix_dim.width
-      < matrix_dim.height)
-    memory_full (SIZE_MAX);
-
   /* Enlarge the glyph pool.  */
   needed = matrix_dim.width;
+  if (INT_MULTIPLY_OVERFLOW (needed, matrix_dim.height))
+    memory_full (SIZE_MAX);
   needed *= matrix_dim.height;
   if (needed > pool->nglyphs)
     {
-      ptrdiff_t size = needed * sizeof (struct glyph);
-      pool->glyphs = (struct glyph *) xrealloc (pool->glyphs, size);
-      memset (pool->glyphs + pool->nglyphs, 0,
-             size - pool->nglyphs * sizeof (struct glyph));
-      pool->nglyphs = needed;
+      ptrdiff_t old_nglyphs = pool->nglyphs;
+      pool->glyphs = xpalloc (pool->glyphs, &pool->nglyphs,
+                             needed - old_nglyphs, -1, sizeof *pool->glyphs);
+      memset (pool->glyphs + old_nglyphs, 0,
+             (pool->nglyphs - old_nglyphs) * sizeof *pool->glyphs);
     }
 
   /* Remember the number of rows and columns because (a) we use them
@@ -4198,12 +4189,12 @@ static ptrdiff_t row_table_size;
    current and desired matrix, and the size of the vectors.  */
 
 static struct row_entry **old_lines, **new_lines;
-static int old_lines_size, new_lines_size;
+static ptrdiff_t old_lines_size, new_lines_size;
 
 /* A pool to allocate run structures from, and its size.  */
 
 static struct run *run_pool;
-static int runs_size;
+static ptrdiff_t runs_size;
 
 /* A vector of runs of lines found during scrolling.  */
 
@@ -4271,7 +4262,7 @@ scrolling_window (struct window *w, int header_line_p)
   ptrdiff_t i;
   int j, first_old, first_new, last_old, last_new;
   int nruns, run_idx;
-  ptrdiff_t n, nbytes;
+  ptrdiff_t n;
   struct row_entry *entry;
   struct redisplay_interface *rif = FRAME_RIF (XFRAME (WINDOW_FRAME (w)));
 
@@ -4356,7 +4347,7 @@ scrolling_window (struct window *w, int header_line_p)
   if (last_new == first_new)
     return 0;
 
-  /* Check for integer overflow in xrealloc size calculation.
+  /* Check for integer overflow in size calculation.
 
      If next_almost_prime checks (N) for divisibility by 2..10, then
      it can return at most N + 10, e.g., next_almost_prime (1) == 11.
@@ -4369,63 +4360,45 @@ scrolling_window (struct window *w, int header_line_p)
   {
     verify (NEXT_ALMOST_PRIME_LIMIT == 11);
     enum { next_almost_prime_increment_max = 10 };
-    ptrdiff_t alloc_max = min (PTRDIFF_MAX, SIZE_MAX);
     ptrdiff_t row_table_max =
-      ((alloc_max - next_almost_prime_increment_max)
-       / (3 * sizeof *row_table));
-    ptrdiff_t row_entry_pool_max = alloc_max / sizeof *row_entry_pool;
-    int n_max = min (INT_MAX, min (row_table_max, row_entry_pool_max));
-    ptrdiff_t old_lines_max = alloc_max / sizeof *old_lines;
-    int current_nrows_max = min (n_max - desired_matrix->nrows, old_lines_max);
-    int desired_nrows_max =
-      min (INT_MAX,
-          alloc_max / max (sizeof *new_lines,
-                           max (sizeof *runs, sizeof *run_pool)));
-    if (current_nrows_max < current_matrix->nrows
-       || desired_nrows_max < desired_matrix->nrows)
+      (min (PTRDIFF_MAX, SIZE_MAX) / (3 * sizeof *row_table)
+       - next_almost_prime_increment_max);
+    ptrdiff_t current_nrows_max = row_table_max - desired_matrix->nrows;
+    if (current_nrows_max < current_matrix->nrows)
       memory_full (SIZE_MAX);
   }
 
   /* Reallocate vectors, tables etc. if necessary.  */
 
   if (current_matrix->nrows > old_lines_size)
-    {
-      nbytes = current_matrix->nrows * sizeof *old_lines;
-      old_lines = (struct row_entry **) xrealloc (old_lines, nbytes);
-      old_lines_size = current_matrix->nrows;
-    }
+    old_lines = xpalloc (old_lines, &old_lines_size,
+                        current_matrix->nrows - old_lines_size,
+                        INT_MAX, sizeof *old_lines);
 
   if (desired_matrix->nrows > new_lines_size)
-    {
-      nbytes = desired_matrix->nrows * sizeof *new_lines;
-      new_lines = (struct row_entry **) xrealloc (new_lines, nbytes);
-      new_lines_size = desired_matrix->nrows;
-    }
+    new_lines = xpalloc (new_lines, &new_lines_size,
+                        desired_matrix->nrows - new_lines_size,
+                        INT_MAX, sizeof *new_lines);
 
   n = desired_matrix->nrows;
   n += current_matrix->nrows;
-  if (row_table_size / 3 < n)
+  if (row_table_size < 3 * n)
     {
       ptrdiff_t size = next_almost_prime (3 * n);
-      nbytes = size * sizeof *row_table;
-      row_table = (struct row_entry **) xrealloc (row_table, nbytes);
+      row_table = xnrealloc (row_table, size, sizeof *row_table);
       row_table_size = size;
-      memset (row_table, 0, nbytes);
+      memset (row_table, 0, size * sizeof *row_table);
     }
 
   if (n > row_entry_pool_size)
-    {
-      nbytes = n * sizeof *row_entry_pool;
-      row_entry_pool = (struct row_entry *) xrealloc (row_entry_pool, nbytes);
-      row_entry_pool_size = n;
-    }
+    row_entry_pool = xpalloc (row_entry_pool, &row_entry_pool_size,
+                             n - row_entry_pool_size,
+                             -1, sizeof *row_entry_pool);
 
   if (desired_matrix->nrows > runs_size)
     {
-      nbytes = desired_matrix->nrows * sizeof *runs;
-      runs = (struct run **) xrealloc (runs, nbytes);
-      nbytes = desired_matrix->nrows * sizeof *run_pool;
-      run_pool = (struct run *) xrealloc (run_pool, nbytes);
+      runs = xnrealloc (runs, desired_matrix->nrows, sizeof *runs);
+      run_pool = xnrealloc (run_pool, desired_matrix->nrows, sizeof *run_pool);
       runs_size = desired_matrix->nrows;
     }
 
index bd1831dde0e3895d745a835ef607cbab131d481a..eb8ff3c25210b5dca17d65b91809307751838916 100644 (file)
--- a/src/doc.c
+++ b/src/doc.c
@@ -174,15 +174,9 @@ get_doc_string (Lisp_Object filepos, int unibyte, int definition)
       if (space_left == 0)
        {
          ptrdiff_t in_buffer = p - get_doc_string_buffer;
-         enum { incr = 16 * 1024 };
-         ptrdiff_t size;
-         if (min (PTRDIFF_MAX, SIZE_MAX) - 1 - incr
-             < get_doc_string_buffer_size)
-           memory_full (SIZE_MAX);
-         size = get_doc_string_buffer_size + incr;
-         get_doc_string_buffer
-           = (char *) xrealloc (get_doc_string_buffer, size + 1);
-         get_doc_string_buffer_size = size;
+         get_doc_string_buffer =
+           xpalloc (get_doc_string_buffer, &get_doc_string_buffer_size,
+                    16 * 1024, -1, 1);
          p = get_doc_string_buffer + in_buffer;
          space_left = (get_doc_string_buffer_size
                        - (p - get_doc_string_buffer));
index 4de567a558851e1e0c9dd5eec40599f4e646d047..e4c42c3e19395f91fa4544d9cd77e6261332ec44 100644 (file)
@@ -1358,27 +1358,17 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
     /* If we have the form --display=NAME,
        convert it into  -d name.
        This requires inserting a new element into argv.  */
-    if (displayname != 0 && skip_args - count_before == 1)
+    if (displayname && count_before < skip_args)
       {
-       char **new;
-       int j;
-
-       if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (char *) - 2 < argc)
-         memory_full (SIZE_MAX);
-       new = (char **) xmalloc (sizeof *new * argc + sizeof *new * 2);
-       for (j = 0; j < count_before + 1; j++)
-         new[j] = argv[j];
-       new[count_before + 1] = (char *) "-d";
-       new[count_before + 2] = displayname;
-       for (j = count_before + 2; j <argc; j++)
-         new[j + 1] = argv[j];
-       argv = new;
-       argc++;
+       if (skip_args == count_before + 1)
+         {
+           memmove (argv + count_before + 3, argv + count_before + 2,
+                    (argc - (count_before + 2)) * sizeof *argv);
+           argv[count_before + 2] = displayname;
+           argc++;
+         }
+       argv[count_before + 1] = (char *) "-d";
       }
-    /* Change --display to -d, when its arg is separate.  */
-    else if (displayname != 0 && skip_args > count_before
-            && argv[count_before + 1][1] == '-')
-      argv[count_before + 1] = (char *) "-d";
 
     if (! no_site_lisp)
       {
@@ -1841,19 +1831,13 @@ sort_args (int argc, char **argv)
      0 for an option that takes no arguments,
      1 for an option that takes one argument, etc.
      -1 for an ordinary non-option argument.  */
-  int *options;
-  int *priority;
+  int *options = xnmalloc (argc, sizeof *options);
+  int *priority = xnmalloc (argc, sizeof *priority);
   int to = 1;
   int incoming_used = 1;
   int from;
   int i;
 
-  if (sizeof (char *) < sizeof (int)
-      && min (PTRDIFF_MAX, SIZE_MAX) / sizeof (int) < argc)
-    memory_full (SIZE_MAX);
-  options = (int *) xmalloc (sizeof (int) * argc);
-  priority = (int *) xmalloc (sizeof (int) * argc);
-
   /* Categorize all the options,
      and figure out which argv elts are option arguments.  */
   for (from = 1; from < argc; from++)
index bcb77574fee510fd71cb2bb7380ff2aa09ee4846..94039b31e172845c6c8c29ea8da854c88b5ea92e 100644 (file)
@@ -3288,8 +3288,7 @@ grow_specpdl (void)
        signal_error ("Variable binding depth exceeds max-specpdl-size", Qnil);
     }
   size = specpdl_size < max_size / 2 ? 2 * specpdl_size : max_size;
-  specpdl = ((struct specbinding *)
-            xrealloc (specpdl, size * sizeof (struct specbinding)));
+  specpdl = xnrealloc (specpdl, size, sizeof *specpdl);
   specpdl_size = size;
   specpdl_ptr = specpdl + count;
 }
index e5538d6acbc36345e29c15ff677fb4ee49f9c304..a3af6b8c15a2a0a3f24d60faba7c57762cb7f516 100644 (file)
--- a/src/fns.c
+++ b/src/fns.c
@@ -602,12 +602,7 @@ concat (ptrdiff_t nargs, Lisp_Object *args,
 
   prev = Qnil;
   if (STRINGP (val))
-    {
-      if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *textprops < nargs)
-       memory_full (SIZE_MAX);
-      SAFE_ALLOCA (textprops, struct textprop_rec *,
-                  sizeof *textprops * nargs);
-    }
+    SAFE_NALLOCA (textprops, 1, nargs);
 
   for (argnum = 0; argnum < nargs; argnum++)
     {
index 551006eef94f342ad9dc55fcfe550ad532c357de..5b95e2b2f08a2613e066b114d8ecbf7ac4086c15 100644 (file)
@@ -1764,18 +1764,10 @@ static OTF_GlyphString otf_gstring;
 static void
 setup_otf_gstring (int size)
 {
-  if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (OTF_Glyph) < size)
-    memory_full (SIZE_MAX);
-
-  if (otf_gstring.size == 0)
+  if (otf_gstring.size < size)
     {
-      otf_gstring.glyphs = (OTF_Glyph *) xmalloc (sizeof (OTF_Glyph) * size);
-      otf_gstring.size = size;
-    }
-  else if (otf_gstring.size < size)
-    {
-      otf_gstring.glyphs = xrealloc (otf_gstring.glyphs,
-                                    sizeof (OTF_Glyph) * size);
+      otf_gstring.glyphs = xnrealloc (otf_gstring.glyphs,
+                                     size, sizeof (OTF_Glyph));
       otf_gstring.size = size;
     }
   otf_gstring.used = size;
@@ -2396,8 +2388,6 @@ ftfont_shape_by_flt (Lisp_Object lgstring, struct font *font,
   struct MFLTFontFT flt_font_ft;
   MFLT *flt = NULL;
   int with_variation_selector = 0;
-  int allocated_max = min (INT_MAX,
-                          min (PTRDIFF_MAX, SIZE_MAX) / sizeof (MFLTGlyph));
 
   if (! m17n_flt_initialized)
     {
@@ -2453,20 +2443,19 @@ ftfont_shape_by_flt (Lisp_Object lgstring, struct font *font,
        }
     }
 
-  if (allocated_max / 2 < len)
+  if (INT_MAX / 2 < len)
     memory_full (SIZE_MAX);
 
   if (gstring.allocated == 0)
     {
-      gstring.allocated = len * 2;
       gstring.glyph_size = sizeof (MFLTGlyph);
-      gstring.glyphs = xmalloc (sizeof (MFLTGlyph) * gstring.allocated);
+      gstring.glyphs = xnmalloc (len * 2, sizeof (MFLTGlyph));
+      gstring.allocated = len * 2;
     }
   else if (gstring.allocated < len * 2)
     {
+      gstring.glyphs = xnrealloc (gstring.glyphs, len * 2, sizeof (MFLTGlyph));
       gstring.allocated = len * 2;
-      gstring.glyphs = xrealloc (gstring.glyphs,
-                                sizeof (MFLTGlyph) * gstring.allocated);
     }
   memset (gstring.glyphs, 0, sizeof (MFLTGlyph) * len);
   for (i = 0; i < len; i++)
@@ -2515,11 +2504,11 @@ ftfont_shape_by_flt (Lisp_Object lgstring, struct font *font,
       int result = mflt_run (&gstring, 0, len, &flt_font_ft.flt_font, flt);
       if (result != -2)
        break;
-      if (allocated_max / 2 < gstring.allocated)
+      if (INT_MAX / 2 < gstring.allocated)
        memory_full (SIZE_MAX);
-      gstring.allocated += gstring.allocated;
-      gstring.glyphs = xrealloc (gstring.glyphs,
-                                sizeof (MFLTGlyph) * gstring.allocated);
+      gstring.glyphs = xnrealloc (gstring.glyphs,
+                                 gstring.allocated, 2 * sizeof (MFLTGlyph));
+      gstring.allocated *= 2;
     }
   if (gstring.used > LGSTRING_GLYPH_LEN (lgstring))
     return Qnil;
index f56e888e685b328fd32dbd1d6660abb4ccc8be82..2492ce620bcb754a719eb024516206b0189d2bbe 100644 (file)
@@ -3318,14 +3318,12 @@ xg_store_widget_in_map (GtkWidget *w)
   if (id_to_widget.max_size == id_to_widget.used)
     {
       ptrdiff_t new_size;
-      ptrdiff_t lim = min (TYPE_MAXIMUM (Window),
-                          min (PTRDIFF_MAX, SIZE_MAX) / sizeof (GtkWidget *));
-      if (lim - ID_TO_WIDGET_INCR < id_to_widget.max_size)
+      if (TYPE_MAXIMUM (Window) - ID_TO_WIDGET_INCR < id_to_widget.max_size)
        memory_full (SIZE_MAX);
 
       new_size = id_to_widget.max_size + ID_TO_WIDGET_INCR;
-      id_to_widget.widgets = xrealloc (id_to_widget.widgets,
-                                       sizeof (GtkWidget *)*new_size);
+      id_to_widget.widgets = xnrealloc (id_to_widget.widgets,
+                                       new_size, sizeof (GtkWidget *));
 
       for (i = id_to_widget.max_size; i < new_size; ++i)
         id_to_widget.widgets[i] = 0;
index d2a71637fed10b1f2d41a64e9a8119f70a24d41a..bf7daa24da1ca73b639fc88cac89f5f89a8c8e4e 100644 (file)
@@ -3586,11 +3586,7 @@ xpm_load (struct frame *f, struct image *img)
 #endif /* HAVE_NTGUI */
 
       /* Remember allocated colors.  */
-      if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof *img->colors
-         < attrs.nalloc_pixels)
-       memory_full (SIZE_MAX);
-      img->colors = (unsigned long *) xmalloc (img->ncolors
-                                              * sizeof *img->colors);
+      img->colors = xnmalloc (attrs.nalloc_pixels, sizeof *img->colors);
       img->ncolors = attrs.nalloc_pixels;
       for (i = 0; i < attrs.nalloc_pixels; ++i)
        {
index 8a2117751aabf69bf0f660da6bc5ddc6baf9009f..37873351aa0fa2f36351952f76c85f26b679769c 100644 (file)
@@ -1423,7 +1423,7 @@ compute_motion (EMACS_INT from, EMACS_INT fromvpos, EMACS_INT fromhpos, int did_
          the text character-by-character.  */
       if (current_buffer->width_run_cache && pos >= next_width_run)
         {
-          EMACS_INT run_end;
+          ptrdiff_t run_end;
           int common_width
             = region_cache_forward (current_buffer,
                                     current_buffer->width_run_cache,
index 267bfe1b21f943821c157eb8c573fb37455a6831..83cc680b7e2850a5fda55e3bfa5db9245fa859a2 100644 (file)
@@ -3574,6 +3574,9 @@ extern int immediate_quit;            /* Nonzero means ^G can quit instantly */
 extern POINTER_TYPE *xmalloc (size_t);
 extern POINTER_TYPE *xrealloc (POINTER_TYPE *, size_t);
 extern void xfree (POINTER_TYPE *);
+extern void *xnmalloc (ptrdiff_t, ptrdiff_t);
+extern void *xnrealloc (void *, ptrdiff_t, ptrdiff_t);
+extern void *xpalloc (void *, ptrdiff_t *, ptrdiff_t, ptrdiff_t, ptrdiff_t);
 
 extern char *xstrdup (const char *);
 
@@ -3691,6 +3694,23 @@ extern Lisp_Object safe_alloca_unwind (Lisp_Object);
       }                                                          \
   } while (0)
 
+/* SAFE_NALLOCA sets BUF to a newly allocated array of MULTIPLIER *
+   NITEMS items, each of the same type as *BUF.  MULTIPLIER must
+   positive.  The code is tuned for MULTIPLIER being a constant.  */
+
+#define SAFE_NALLOCA(buf, multiplier, nitems)                  \
+  do {                                                         \
+    if ((nitems) <= MAX_ALLOCA / sizeof *(buf) / (multiplier)) \
+      (buf) = alloca (sizeof *(buf) * (multiplier) * (nitems));        \
+    else                                                       \
+      {                                                                 \
+       (buf) = xnmalloc (nitems, sizeof *(buf) * (multiplier)); \
+       sa_must_free = 1;                                        \
+       record_unwind_protect (safe_alloca_unwind,               \
+                              make_save_value (buf, 0));        \
+      }                                                                 \
+  } while (0)
+
 /* SAFE_FREE frees xmalloced memory and enables GC as needed.  */
 
 #define SAFE_FREE()                    \
index 30082af90376d4c1e7f36ace4d075a1bd3ef45e5..eb564a10ec6f8099590ec36ec0e6d7823e0a0500 100644 (file)
@@ -261,10 +261,7 @@ read_minibuf_noninteractive (Lisp_Object map, Lisp_Object initial,
          if (len == size)
            {
              if (STRING_BYTES_BOUND / 2 < size)
-               {
-                 xfree (line);
-                 memory_full (SIZE_MAX);
-               }
+               memory_full (SIZE_MAX);
              size *= 2;
              line = (char *) xrealloc (line, size);
            }
index 2ce996dc82fc92f7e928c28314a78756458e4f5a..484e8847dc9a0cd00559abd1892efe06a7a00bb3 100644 (file)
@@ -1376,19 +1376,9 @@ ns_index_color (NSColor *color, struct frame *f)
   else
     {
       if (color_table->avail == color_table->size)
-        {
-         ptrdiff_t size;
-         ptrdiff_t size_max =
-           min (ULONG_MAX,
-                min (PTRDIFF_MAX, SIZE_MAX) / sizeof (NSColor *));
-         if (size_max - NS_COLOR_CAPACITY < color_table->size)
-           memory_full (SIZE_MAX);
-         size = color_table->size + NS_COLOR_CAPACITY;
-          color_table->colors
-           = (NSColor **)xrealloc (color_table->colors,
-                                   size * sizeof (NSColor *));
-         color_table->size = size;
-        }
+       color_table->colors =
+         xpalloc (color_table->colors, &color_table->size, 1,
+                  min (ULONG_MAX, PTRDIFF_MAX), sizeof *color_table->colors);
       idx = color_table->avail++;
     }
 
index 31359a1f1f2a96de0f5a969cf400d5cc7fc60c10..f2c2bfd81c56355cb1427871a2f5b983ef976bee 100644 (file)
@@ -3558,7 +3558,7 @@ format; see the description of ADDRESS in `make-network-process'.  */)
 {
   struct ifconf ifconf;
   struct ifreq *ifreqs = NULL;
-  int ifaces = 0;
+  ptrdiff_t ifaces = 0;
   int buf_size, s;
   Lisp_Object res;
 
@@ -3567,21 +3567,9 @@ format; see the description of ADDRESS in `make-network-process'.  */)
     return Qnil;
 
  again:
-  if (min (INT_MAX, min (PTRDIFF_MAX, SIZE_MAX)) / sizeof *ifreqs - 25
-      < ifaces)
-    {
-      xfree (ifreqs);
-      memory_full (SIZE_MAX);
-    }
-  ifaces += 25;
+  ifreqs = xpalloc (ifreqs, &ifaces, 25,
+                   INT_MAX / sizeof *ifreqs, sizeof *ifreqs);
   buf_size = ifaces * sizeof (ifreqs[0]);
-  ifreqs = (struct ifreq *)xrealloc(ifreqs, buf_size);
-  if (!ifreqs)
-    {
-      close (s);
-      return Qnil;
-    }
-
   ifconf.ifc_len = buf_size;
   ifconf.ifc_req = ifreqs;
   if (ioctl (s, SIOCGIFCONF, &ifconf))
index e6cec96171df783cd9ef69b5a394135ff0fbfc53..ed7a07a67097470173ea703f239e7e974391e47a 100644 (file)
@@ -63,7 +63,7 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
    revalidate_region_cache to see how this helps.  */
 
 struct boundary {
-  EMACS_INT pos;
+  ptrdiff_t pos;
   int value;
 };
 
@@ -73,16 +73,16 @@ struct region_cache {
   struct boundary *boundaries;
 
   /* boundaries[gap_start ... gap_start + gap_len - 1] is the gap.  */
-  EMACS_INT gap_start, gap_len;
+  ptrdiff_t gap_start, gap_len;
 
   /* The number of elements allocated to boundaries, not including the
      gap.  */
-  EMACS_INT cache_len;
+  ptrdiff_t cache_len;
 
   /* The areas that haven't changed since the last time we cleaned out
      invalid entries from the cache.  These overlap when the buffer is
      entirely unchanged.  */
-  EMACS_INT beg_unchanged, end_unchanged;
+  ptrdiff_t beg_unchanged, end_unchanged;
 
   /* The first and last positions in the buffer.  Because boundaries
      store their positions relative to the start (BEG) and end (Z) of
@@ -92,7 +92,7 @@ struct region_cache {
 
      Yes, buffer_beg is always 1.  It's there for symmetry with
      buffer_end and the BEG and BUF_BEG macros.  */
-  EMACS_INT buffer_beg, buffer_end;
+  ptrdiff_t buffer_beg, buffer_end;
 };
 
 /* Return the position of boundary i in cache c.  */
@@ -173,17 +173,17 @@ free_region_cache (struct region_cache *c)
    This operation should be logarithmic in the number of cache
    entries.  It would be nice if it took advantage of locality of
    reference, too, by searching entries near the last entry found.  */
-static EMACS_INT
-find_cache_boundary (struct region_cache *c, EMACS_INT pos)
+static ptrdiff_t
+find_cache_boundary (struct region_cache *c, ptrdiff_t pos)
 {
-  EMACS_INT low = 0, high = c->cache_len;
+  ptrdiff_t low = 0, high = c->cache_len;
 
   while (low + 1 < high)
     {
       /* mid is always a valid index, because low < high and ">> 1"
          rounds down.  */
-      EMACS_INT mid = (low + high) >> 1;
-      EMACS_INT boundary = BOUNDARY_POS (c, mid);
+      ptrdiff_t mid = (low >> 1) + (high >> 1) + (low & high & 1);
+      ptrdiff_t boundary = BOUNDARY_POS (c, mid);
 
       if (pos < boundary)
         high = mid;
@@ -208,13 +208,13 @@ find_cache_boundary (struct region_cache *c, EMACS_INT pos)
 /* Move the gap of cache C to index POS, and make sure it has space
    for at least MIN_SIZE boundaries.  */
 static void
-move_cache_gap (struct region_cache *c, EMACS_INT pos, EMACS_INT min_size)
+move_cache_gap (struct region_cache *c, ptrdiff_t pos, ptrdiff_t min_size)
 {
   /* Copy these out of the cache and into registers.  */
-  EMACS_INT gap_start = c->gap_start;
-  EMACS_INT gap_len = c->gap_len;
-  EMACS_INT buffer_beg = c->buffer_beg;
-  EMACS_INT buffer_end = c->buffer_end;
+  ptrdiff_t gap_start = c->gap_start;
+  ptrdiff_t gap_len = c->gap_len;
+  ptrdiff_t buffer_beg = c->buffer_beg;
+  ptrdiff_t buffer_end = c->buffer_end;
 
   if (pos < 0
       || pos > c->cache_len)
@@ -246,22 +246,11 @@ move_cache_gap (struct region_cache *c, EMACS_INT pos, EMACS_INT min_size)
      when the portion after the gap is smallest.  */
   if (gap_len < min_size)
     {
-      EMACS_INT i;
-      ptrdiff_t cache_len_max =
-       min (PTRDIFF_MAX, SIZE_MAX) / sizeof *c->boundaries;
-      ptrdiff_t min_size_max = cache_len_max - c->cache_len;
-
-      if (min_size_max < min_size)
-       memory_full (SIZE_MAX);
-
-      /* Unless running out of space, make at least NEW_CACHE_GAP
-         elements, as long as we're expanding anyway.  */
-      min_size = max (min_size, min (min_size_max, NEW_CACHE_GAP));
+      ptrdiff_t i;
 
       c->boundaries =
-        (struct boundary *) xrealloc (c->boundaries,
-                                      ((min_size + c->cache_len)
-                                       * sizeof (*c->boundaries)));
+       xpalloc (c->boundaries, &c->cache_len, min_size, -1,
+                sizeof *c->boundaries);
 
       /* Some systems don't provide a version of the copy routine that
          can be trusted to shift memory upward into an overlapping
@@ -298,7 +287,7 @@ move_cache_gap (struct region_cache *c, EMACS_INT pos, EMACS_INT min_size)
 /* Insert a new boundary in cache C; it will have cache index I,
    and have the specified POS and VALUE.  */
 static void
-insert_cache_boundary (struct region_cache *c, EMACS_INT i, EMACS_INT pos,
+insert_cache_boundary (struct region_cache *c, ptrdiff_t i, ptrdiff_t pos,
                       int value)
 {
   /* i must be a valid cache index.  */
@@ -336,9 +325,9 @@ insert_cache_boundary (struct region_cache *c, EMACS_INT i, EMACS_INT pos,
 
 static void
 delete_cache_boundaries (struct region_cache *c,
-                        EMACS_INT start, EMACS_INT end)
+                        ptrdiff_t start, ptrdiff_t end)
 {
-  EMACS_INT len = end - start;
+  ptrdiff_t len = end - start;
 
   /* Gotta be in range.  */
   if (start < 0
@@ -389,7 +378,7 @@ delete_cache_boundaries (struct region_cache *c,
 /* Set the value in cache C for the region START..END to VALUE.  */
 static void
 set_cache_region (struct region_cache *c,
-                 EMACS_INT start, EMACS_INT end, int value)
+                 ptrdiff_t start, ptrdiff_t end, int value)
 {
   if (start > end)
     abort ();
@@ -412,8 +401,8 @@ set_cache_region (struct region_cache *c,
        index of the earliest boundary after the last character in
        start..end.  (This tortured terminology is intended to answer
        all the "< or <=?" sort of questions.)  */
-    EMACS_INT start_ix = find_cache_boundary (c, start);
-    EMACS_INT end_ix   = find_cache_boundary (c, end - 1) + 1;
+    ptrdiff_t start_ix = find_cache_boundary (c, start);
+    ptrdiff_t end_ix   = find_cache_boundary (c, end - 1) + 1;
 
     /* We must remember the value established by the last boundary
        before end; if that boundary's domain stretches beyond end,
@@ -491,7 +480,7 @@ set_cache_region (struct region_cache *c,
    args to pass are the same before and after such an operation.)  */
 void
 invalidate_region_cache (struct buffer *buf, struct region_cache *c,
-                        EMACS_INT head, EMACS_INT tail)
+                        ptrdiff_t head, ptrdiff_t tail)
 {
   /* Let chead = c->beg_unchanged, and
          ctail = c->end_unchanged.
@@ -629,7 +618,7 @@ revalidate_region_cache (struct buffer *buf, struct region_cache *c)
      corresponds to the modified region of the buffer.  */
   else
     {
-      EMACS_INT modified_ix;
+      ptrdiff_t modified_ix;
 
       /* These positions are correct, relative to both the cache basis
          and the buffer basis.  */
@@ -698,7 +687,7 @@ revalidate_region_cache (struct buffer *buf, struct region_cache *c)
    no newlines", in the case of the line cache).  */
 void
 know_region_cache (struct buffer *buf, struct region_cache *c,
-                  EMACS_INT start, EMACS_INT end)
+                  ptrdiff_t start, ptrdiff_t end)
 {
   revalidate_region_cache (buf, c);
 
@@ -713,14 +702,14 @@ know_region_cache (struct buffer *buf, struct region_cache *c,
    position after POS where the knownness changes.  */
 int
 region_cache_forward (struct buffer *buf, struct region_cache *c,
-                     EMACS_INT pos, EMACS_INT *next)
+                     ptrdiff_t pos, ptrdiff_t *next)
 {
   revalidate_region_cache (buf, c);
 
   {
-    EMACS_INT i = find_cache_boundary (c, pos);
+    ptrdiff_t i = find_cache_boundary (c, pos);
     int i_value = BOUNDARY_VALUE (c, i);
-    EMACS_INT j;
+    ptrdiff_t j;
 
     /* Beyond the end of the buffer is unknown, by definition.  */
     if (pos >= BUF_Z (buf))
@@ -749,7 +738,7 @@ region_cache_forward (struct buffer *buf, struct region_cache *c,
    the purposes of CACHE.  If NEXT is non-zero, set *NEXT to the nearest
    position before POS where the knownness changes.  */
 int region_cache_backward (struct buffer *buf, struct region_cache *c,
-                          EMACS_INT pos, EMACS_INT *next)
+                          ptrdiff_t pos, ptrdiff_t *next)
 {
   revalidate_region_cache (buf, c);
 
@@ -762,9 +751,9 @@ int region_cache_backward (struct buffer *buf, struct region_cache *c,
     }
 
   {
-    EMACS_INT i = find_cache_boundary (c, pos - 1);
+    ptrdiff_t i = find_cache_boundary (c, pos - 1);
     int i_value = BOUNDARY_VALUE (c, i);
-    EMACS_INT j;
+    ptrdiff_t j;
 
     if (next)
       {
@@ -790,18 +779,18 @@ void pp_cache (struct region_cache *) EXTERNALLY_VISIBLE;
 void
 pp_cache (struct region_cache *c)
 {
-  int i;
-  EMACS_INT beg_u = c->buffer_beg + c->beg_unchanged;
-  EMACS_INT end_u = c->buffer_end - c->end_unchanged;
+  ptrdiff_t i;
+  ptrdiff_t beg_u = c->buffer_beg + c->beg_unchanged;
+  ptrdiff_t end_u = c->buffer_end - c->end_unchanged;
 
   fprintf (stderr,
-           "basis: %"pI"d..%"pI"d    modified: %"pI"d..%"pI"d\n",
+           "basis: %"pD"d..%"pD"d    modified: %"pD"d..%"pD"d\n",
            c->buffer_beg, c->buffer_end,
            beg_u, end_u);
 
   for (i = 0; i < c->cache_len; i++)
     {
-      EMACS_INT pos = BOUNDARY_POS (c, i);
+      ptrdiff_t pos = BOUNDARY_POS (c, i);
 
       putc (((pos < beg_u) ? 'v'
              : (pos == beg_u) ? '-'
@@ -811,6 +800,6 @@ pp_cache (struct region_cache *c)
              : (pos == end_u) ? '-'
              : ' '),
             stderr);
-      fprintf (stderr, "%"pI"d : %d\n", pos, BOUNDARY_VALUE (c, i));
+      fprintf (stderr, "%"pD"d : %d\n", pos, BOUNDARY_VALUE (c, i));
     }
 }
index ea767ed0dc35ff48c1f93175753b370c3b900acb..8e1be7167763602919bfb83402fe3b6b32258d37 100644 (file)
@@ -72,7 +72,7 @@ void free_region_cache (struct region_cache *);
    no newlines", in the case of the line cache).  */
 extern void know_region_cache (struct buffer *BUF,
                                struct region_cache *CACHE,
-                               EMACS_INT START, EMACS_INT END);
+                               ptrdiff_t START, ptrdiff_t END);
 
 /* Indicate that a section of BUF has changed, to invalidate CACHE.
    HEAD is the number of chars unchanged at the beginning of the buffer.
@@ -84,7 +84,7 @@ extern void know_region_cache (struct buffer *BUF,
    args to pass are the same before and after such an operation.)  */
 extern void invalidate_region_cache (struct buffer *BUF,
                                      struct region_cache *CACHE,
-                                     EMACS_INT HEAD, EMACS_INT TAIL);
+                                     ptrdiff_t HEAD, ptrdiff_t TAIL);
 
 /* The scanning functions.
 
@@ -100,13 +100,13 @@ extern void invalidate_region_cache (struct buffer *BUF,
    position after POS where the knownness changes.  */
 extern int region_cache_forward (struct buffer *BUF,
                                  struct region_cache *CACHE,
-                                 EMACS_INT POS,
-                                 EMACS_INT *NEXT);
+                                 ptrdiff_t POS,
+                                 ptrdiff_t *NEXT);
 
 /* Return true if the text immediately before POS in BUF is known, for
    the purposes of CACHE.  If NEXT is non-zero, set *NEXT to the nearest
    position before POS where the knownness changes.  */
 extern int region_cache_backward (struct buffer *BUF,
                                   struct region_cache *CACHE,
-                                  EMACS_INT POS,
-                                  EMACS_INT *NEXT);
+                                  ptrdiff_t POS,
+                                  ptrdiff_t *NEXT);
index 9184919f0cef974f947903201b6346b04767ba57..05f6fdf85f05934caa5ac8c5763d815de174d24d 100644 (file)
@@ -969,21 +969,14 @@ do_line_insertion_deletion_costs (FRAME_PTR frame,
                                  const char *cleanup_string,
                                  int coefficient)
 {
-  if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (int) < FRAME_LINES (frame))
-    memory_full (SIZE_MAX);
-
   FRAME_INSERT_COST (frame) =
-    (int *) xrealloc (FRAME_INSERT_COST (frame),
-                     FRAME_LINES (frame) * sizeof (int));
+    xnrealloc (FRAME_INSERT_COST (frame), FRAME_LINES (frame), sizeof (int));
   FRAME_DELETEN_COST (frame) =
-    (int *) xrealloc (FRAME_DELETEN_COST (frame),
-                     FRAME_LINES (frame) * sizeof (int));
+    xnrealloc (FRAME_DELETEN_COST (frame), FRAME_LINES (frame), sizeof (int));
   FRAME_INSERTN_COST (frame) =
-    (int *) xrealloc (FRAME_INSERTN_COST (frame),
-                     FRAME_LINES (frame) * sizeof (int));
+    xnrealloc (FRAME_INSERTN_COST (frame), FRAME_LINES (frame), sizeof (int));
   FRAME_DELETE_COST (frame) =
-    (int *) xrealloc (FRAME_DELETE_COST (frame),
-                     FRAME_LINES (frame) * sizeof (int));
+    xnrealloc (FRAME_DELETE_COST (frame), FRAME_LINES (frame), sizeof (int));
 
   ins_del_costs (frame,
                 ins_line_string, multi_ins_string,
index 79ef8b046df448fdfed3a24a76c001a5d26d410a..d892792cbaa348b38783d7350d6d31772b6c6122 100644 (file)
@@ -683,7 +683,7 @@ scan_buffer (register int target, EMACS_INT start, EMACS_INT end,
            to see where we can avoid some scanning.  */
         if (target == '\n' && newline_cache)
           {
-            EMACS_INT next_change;
+            ptrdiff_t next_change;
             immediate_quit = 0;
             while (region_cache_forward
                    (current_buffer, newline_cache, start_byte, &next_change))
@@ -755,7 +755,7 @@ scan_buffer (register int target, EMACS_INT start, EMACS_INT end,
         /* Consult the newline cache, if appropriate.  */
         if (target == '\n' && newline_cache)
           {
-            EMACS_INT next_change;
+            ptrdiff_t next_change;
             immediate_quit = 0;
             while (region_cache_backward
                    (current_buffer, newline_cache, start_byte, &next_change))
@@ -2640,17 +2640,17 @@ since only regular expressions have distinguished subexpressions.  */)
      perform substitution on the replacement string.  */
   if (NILP (literal))
     {
-      EMACS_INT length = SBYTES (newtext);
+      ptrdiff_t length = SBYTES (newtext);
       unsigned char *substed;
-      EMACS_INT substed_alloc_size, substed_len;
+      ptrdiff_t substed_alloc_size, substed_len;
       int buf_multibyte = !NILP (BVAR (current_buffer, enable_multibyte_characters));
       int str_multibyte = STRING_MULTIBYTE (newtext);
       int really_changed = 0;
 
-      substed_alloc_size = length * 2 + 100;
-      if (min (PTRDIFF_MAX, SIZE_MAX) - 1 < substed_alloc_size)
-       memory_full (SIZE_MAX);
-      substed = (unsigned char *) xmalloc (substed_alloc_size + 1);
+      substed_alloc_size = ((STRING_BYTES_BOUND - 100) / 2 < length
+                           ? STRING_BYTES_BOUND
+                           : length * 2 + 100);
+      substed = (unsigned char *) xmalloc (substed_alloc_size);
       substed_len = 0;
 
       /* Go thru NEWTEXT, producing the actual text to insert in
@@ -2661,7 +2661,7 @@ since only regular expressions have distinguished subexpressions.  */)
        {
          unsigned char str[MAX_MULTIBYTE_LENGTH];
          const unsigned char *add_stuff = NULL;
-         EMACS_INT add_len = 0;
+         ptrdiff_t add_len = 0;
          int idx = -1;
 
          if (str_multibyte)
@@ -2725,7 +2725,7 @@ since only regular expressions have distinguished subexpressions.  */)
             set up ADD_STUFF and ADD_LEN to point to it.  */
          if (idx >= 0)
            {
-             EMACS_INT begbyte = CHAR_TO_BYTE (search_regs.start[idx]);
+             ptrdiff_t begbyte = CHAR_TO_BYTE (search_regs.start[idx]);
              add_len = CHAR_TO_BYTE (search_regs.end[idx]) - begbyte;
              if (search_regs.start[idx] < GPT && GPT < search_regs.end[idx])
                move_gap (search_regs.start[idx]);
@@ -2736,19 +2736,11 @@ since only regular expressions have distinguished subexpressions.  */)
             is invariably ADD_LEN bytes starting at ADD_STUFF.  */
 
          /* Make sure SUBSTED is big enough.  */
-         if (substed_len + add_len >= substed_alloc_size)
-           {
-             ptrdiff_t add_len_max =
-               min (PTRDIFF_MAX, SIZE_MAX) - 1 - 500 - substed_len;
-             if (add_len_max < add_len)
-               {
-                 xfree (substed);
-                 memory_full (SIZE_MAX);
-               }
-             substed_alloc_size = substed_len + add_len + 500;
-             substed = (unsigned char *) xrealloc (substed,
-                                                   substed_alloc_size + 1);
-           }
+         if (substed_alloc_size - substed_len < add_len)
+           substed =
+             xpalloc (substed, &substed_alloc_size,
+                      add_len - (substed_alloc_size - substed_len),
+                      STRING_BYTES_BOUND, 1);
 
          /* Now add to the end of SUBSTED.  */
          if (add_stuff)
@@ -3000,30 +2992,17 @@ If optional arg RESEAT is non-nil, make markers on LIST point nowhere.  */)
 
     if (length > search_regs.num_regs)
       {
-       if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (regoff_t) < length)
-         memory_full (SIZE_MAX);
-
-       if (search_regs.num_regs == 0)
-         {
-           search_regs.start
-             = (regoff_t *) xmalloc (length * sizeof (regoff_t));
-           search_regs.end
-             = (regoff_t *) xmalloc (length * sizeof (regoff_t));
-         }
-       else
-         {
-           search_regs.start
-             = (regoff_t *) xrealloc (search_regs.start,
-                                      length * sizeof (regoff_t));
-           search_regs.end
-             = (regoff_t *) xrealloc (search_regs.end,
-                                      length * sizeof (regoff_t));
-         }
-
-       for (i = search_regs.num_regs; i < length; i++)
+       ptrdiff_t num_regs = search_regs.num_regs;
+       search_regs.start =
+         xpalloc (search_regs.start, &num_regs, length - num_regs,
+                  min (PTRDIFF_MAX, UINT_MAX), sizeof (regoff_t));
+       search_regs.end =
+         xrealloc (search_regs.end, num_regs * sizeof (regoff_t));
+
+       for (i = search_regs.num_regs; i < num_regs; i++)
          search_regs.start[i] = -1;
 
-       search_regs.num_regs = length;
+       search_regs.num_regs = num_regs;
       }
 
     for (i = 0; CONSP (list); i++)
index bc6fa8f80f98a79415e6cfcaabaf42a58006f159..f3bf3a947cb328e3b568cd5bb916ea880f2910c1 100644 (file)
@@ -551,12 +551,10 @@ encode_terminal_code (struct glyph *src, int src_len, struct coding_system *codi
 
          if (encode_terminal_src_size - nbytes < required)
            {
-             ptrdiff_t size;
-             if (min (PTRDIFF_MAX, SIZE_MAX) - nbytes < required)
-               memory_full (SIZE_MAX);
-             size = nbytes + required;
-             encode_terminal_src = xrealloc (encode_terminal_src, size);
-             encode_terminal_src_size = size;
+             encode_terminal_src =
+               xpalloc (encode_terminal_src, &encode_terminal_src_size,
+                        required - (encode_terminal_src_size - nbytes),
+                        -1, 1);
              buf = encode_terminal_src + nbytes;
            }
 
@@ -629,13 +627,9 @@ encode_terminal_code (struct glyph *src, int src_len, struct coding_system *codi
              nbytes = buf - encode_terminal_src;
              if (encode_terminal_src_size - nbytes < MAX_MULTIBYTE_LENGTH)
                {
-                 ptrdiff_t size;
-                 if (min (PTRDIFF_MAX, SIZE_MAX) - MAX_MULTIBYTE_LENGTH
-                     < nbytes)
-                   memory_full (SIZE_MAX);
-                 size = nbytes + MAX_MULTIBYTE_LENGTH;
-                 encode_terminal_src = xrealloc (encode_terminal_src, size);
-                 encode_terminal_src_size = size;
+                 encode_terminal_src =
+                   xpalloc (encode_terminal_src, &encode_terminal_src_size,
+                            MAX_MULTIBYTE_LENGTH, -1, 1);
                  buf = encode_terminal_src + nbytes;
                }
              if (CHAR_BYTE8_P (c)
@@ -665,12 +659,11 @@ encode_terminal_code (struct glyph *src, int src_len, struct coding_system *codi
              nbytes = buf - encode_terminal_src;
              if (encode_terminal_src_size - nbytes < SBYTES (string))
                {
-                 ptrdiff_t size;
-                 if (min (PTRDIFF_MAX, SIZE_MAX) - SBYTES (string) < nbytes)
-                   memory_full (SIZE_MAX);
-                 size = nbytes + SBYTES (string);
-                 encode_terminal_src = xrealloc (encode_terminal_src, size);
-                 encode_terminal_src_size = size;
+                 encode_terminal_src =
+                   xpalloc (encode_terminal_src, &encode_terminal_src_size,
+                            (SBYTES (string)
+                             - (encode_terminal_src_size - nbytes)),
+                            -1, 1);
                  buf = encode_terminal_src + nbytes;
                }
              memcpy (buf, SDATA (string), SBYTES (string));
@@ -1161,16 +1154,16 @@ calculate_costs (struct frame *frame)
          X turns off char_ins_del_ok. */
 
       max_frame_cols = max (max_frame_cols, FRAME_COLS (frame));
-      if ((min (PTRDIFF_MAX, SIZE_MAX) / sizeof (int) - 1) / 2 < max_frame_cols)
+      if ((min (PTRDIFF_MAX, SIZE_MAX) / sizeof (int) - 1) / 2
+         < max_frame_cols)
        memory_full (SIZE_MAX);
 
-      char_ins_del_vector
-       = (int *) xrealloc (char_ins_del_vector,
-                           (sizeof (int)
-                            + 2 * max_frame_cols * sizeof (int)));
+      char_ins_del_vector =
+       xrealloc (char_ins_del_vector,
+                 (sizeof (int) + 2 * sizeof (int) * max_frame_cols));
 
       memset (char_ins_del_vector, 0,
-             (sizeof (int) + 2 * max_frame_cols * sizeof (int)));
+             (sizeof (int) + 2 * sizeof (int) * max_frame_cols));
 
 
       if (f && (!tty->TS_ins_line && !tty->TS_del_line))
index 791c593c06faa265ded8302c4c01646911bbeb49..6f24817fa7265a6714af287c983e394e9b48276c 100644 (file)
@@ -637,13 +637,10 @@ gobble_line (int fd, register struct termcap_buffer *bufp, char *append_end)
            {
              ptrdiff_t ptr_offset = bufp->ptr - buf;
              ptrdiff_t append_end_offset = append_end - buf;
-             ptrdiff_t size;
-             if ((min (PTRDIFF_MAX, SIZE_MAX) - 1) / 2 < bufp->size)
-               memory_full (SIZE_MAX);
-             size = 2 * bufp->size;
              /* Add 1 to size to ensure room for terminating null.  */
-             bufp->beg = buf = (char *) xrealloc (buf, size + 1);
-             bufp->size = size;
+             ptrdiff_t size = bufp->size + 1;
+             bufp->beg = buf = xpalloc (buf, &size, 1, -1, 1);
+             bufp->size = size - 1;
              bufp->ptr = buf + ptr_offset;
              append_end = buf + append_end_offset;
            }
index 06cec873153cdba5f35421fb6aab15c0748c6228..ac21667d65bf8e2288736562dd64f41176973fd9 100644 (file)
@@ -101,18 +101,13 @@ tparam1 (const char *string, char *outstring, int len,
 
          if (outlen == 0)
            {
-             if (min (PTRDIFF_MAX, SIZE_MAX) - 40 < len)
-               goto out_of_memory;
              outlen = len + 40;
              new = (char *) xmalloc (outlen);
              memcpy (new, outstring, offset);
            }
          else
            {
-             if (min (PTRDIFF_MAX, SIZE_MAX) / 2 < outlen)
-               goto out_of_memory;
-             outlen *= 2;
-             new = (char *) xrealloc (outstring, outlen);
+             new = xpalloc (outstring, &outlen, 1, -1, 1);
            }
 
          op = new + offset;
@@ -178,12 +173,8 @@ tparam1 (const char *string, char *outstring, int len,
                        doup++, append_len_incr = strlen (up);
                      else
                        doleft++, append_len_incr = strlen (left);
-                     if (PTRDIFF_MAX - append_len < append_len_incr)
-                       {
-                       out_of_memory:
-                         xfree (new);
-                         memory_full (SIZE_MAX);
-                       }
+                     if (INT_ADD_OVERFLOW (append_len, append_len_incr))
+                       memory_full (SIZE_MAX);
                      append_len += append_len_incr;
                    }
                }
@@ -286,7 +277,7 @@ main (int argc, char **argv)
   args[0] = atoi (argv[2]);
   args[1] = atoi (argv[3]);
   args[2] = atoi (argv[4]);
-  tparam1 (argv[1], buf, "LEFT", "UP", args);
+  tparam1 (argv[1], buf, 50, "LEFT", "UP", args);
   printf ("%s\n", buf);
   return 0;
 }
index d44e677eeb7859b2899cf2ca0ffac1bd31518291..b64a2c0cf6c57dc5562a4bd0854421b589339ff0 100644 (file)
@@ -10384,17 +10384,14 @@ static void
 store_mode_line_noprop_char (char c)
 {
   /* If output position has reached the end of the allocated buffer,
-     double the buffer's size.  */
+     increase the buffer's size.  */
   if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
     {
       ptrdiff_t len = MODE_LINE_NOPROP_LEN (0);
-      ptrdiff_t new_size;
-
-      if (STRING_BYTES_BOUND / 2 < len)
-       memory_full (SIZE_MAX);
-      new_size = 2 * len;
-      mode_line_noprop_buf = (char *) xrealloc (mode_line_noprop_buf, new_size);
-      mode_line_noprop_buf_end = mode_line_noprop_buf + new_size;
+      ptrdiff_t size = len;
+      mode_line_noprop_buf =
+       xpalloc (mode_line_noprop_buf, &size, 1, STRING_BYTES_BOUND, 1);
+      mode_line_noprop_buf_end = mode_line_noprop_buf + size;
       mode_line_noprop_ptr = mode_line_noprop_buf + len;
     }
 
index 352fdb4b082bd33f337c8f092ce793df21c5310e..53b30a5c1c281aad3174d60f95e71cb8fa3f4b55 100644 (file)
@@ -403,7 +403,7 @@ static int next_lface_id;
 /* A vector mapping Lisp face Id's to face names.  */
 
 static Lisp_Object *lface_id_to_name;
-static int lface_id_to_name_size;
+static ptrdiff_t lface_id_to_name_size;
 
 /* TTY color-related functions (defined in tty-colors.el).  */
 
@@ -2667,17 +2667,10 @@ Value is a vector of face attributes.  */)
         The mapping from Lisp face to Lisp face id is given by the
         property `face' of the Lisp face name.  */
       if (next_lface_id == lface_id_to_name_size)
-       {
-         ptrdiff_t new_size, sz;
-         if (min (min (PTRDIFF_MAX, SIZE_MAX) / 2 / sizeof *lface_id_to_name,
-                  MOST_POSITIVE_FIXNUM)
-             < lface_id_to_name_size)
-           memory_full (SIZE_MAX);
-         new_size = max (50, 2 * lface_id_to_name_size);
-         sz = new_size * sizeof *lface_id_to_name;
-         lface_id_to_name = (Lisp_Object *) xrealloc (lface_id_to_name, sz);
-         lface_id_to_name_size = new_size;
-       }
+       lface_id_to_name =
+         xpalloc (lface_id_to_name, &lface_id_to_name_size, 1,
+                  min (INT_MAX, MOST_POSITIVE_FIXNUM),
+                  sizeof *lface_id_to_name);
 
       lface_id_to_name[next_lface_id] = face;
       Fput (face, Qface, make_number (next_lface_id));
@@ -4415,18 +4408,8 @@ cache_face (struct face_cache *c, struct face *face, unsigned int hash)
   if (i == c->used)
     {
       if (c->used == c->size)
-       {
-         int new_size, sz;
-         new_size =
-           min (2 * c->size,
-                min (MAX_FACE_ID,
-                     min (PTRDIFF_MAX, SIZE_MAX) / sizeof *c->faces_by_id));
-         if (new_size == c->size)
-           abort ();  /* Alternatives?  ++kfs */
-         sz = new_size * sizeof *c->faces_by_id;
-         c->faces_by_id = (struct face **) xrealloc (c->faces_by_id, sz);
-         c->size = new_size;
-       }
+       c->faces_by_id = xpalloc (c->faces_by_id, &c->size, 1, MAX_FACE_ID,
+                                 sizeof *c->faces_by_id);
       c->used++;
     }
 
index 1169acb3cf5643d1c547735921bf1cf36c9755fc..9a3d5fcda83daa39aa91aec8020bb1d948db0251 100644 (file)
@@ -1490,10 +1490,8 @@ x_encode_text (Lisp_Object string, Lisp_Object coding_system, int selectionp,
   coding.mode |= (CODING_MODE_SAFE_ENCODING | CODING_MODE_LAST_BLOCK);
   /* We suppress producing escape sequences for composition.  */
   coding.common_flags &= ~CODING_ANNOTATION_MASK;
-  if (min (PTRDIFF_MAX, SIZE_MAX) / 2 < SCHARS (string))
-    memory_full (SIZE_MAX);
+  coding.destination = xnmalloc (SCHARS (string), 2);
   coding.dst_bytes = SCHARS (string) * 2;
-  coding.destination = (unsigned char *) xmalloc (coding.dst_bytes);
   encode_coding_object (&coding, string, 0, 0,
                        SCHARS (string), SBYTES (string), Qnil);
   *text_bytes = coding.produced;
@@ -4214,9 +4212,7 @@ FRAME.  Default is to change on the edit X window.  */)
         This applies even if long is more than 32 bits.  The X library
         converts to 32 bits before sending to the X server.  */
       elsize = element_format == 32 ? sizeof (long) : element_format >> 3;
-      if (min (PTRDIFF_MAX, SIZE_MAX) / elsize < nelements)
-       memory_full (SIZE_MAX);
-      data = (unsigned char *) xmalloc (nelements * elsize);
+      data = xnmalloc (nelements, elsize);
 
       x_fill_property_data (FRAME_X_DISPLAY (f), value, data, element_format);
     }
index d1844610077d94b1324628802c4399f3b9115ff5..339ec475117c2f3a2d92e381f38a1bf36c38120d 100644 (file)
@@ -29,7 +29,7 @@ along with GNU Emacs.  If not, see <http§://www.gnu.org/licenses/>.  */
 #include <setjmp.h>
 
 static GPollFD *gfds;
-static int gfds_size;
+static ptrdiff_t gfds_size;
 
 int
 xg_select (int max_fds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
@@ -54,16 +54,9 @@ xg_select (int max_fds, SELECT_TYPE *rfds, SELECT_TYPE *wfds, SELECT_TYPE *efds,
   do {
     if (n_gfds > gfds_size)
       {
-       int gfds_size_max =
-         min (INT_MAX, min (PTRDIFF_MAX, SIZE_MAX) / sizeof *gfds);
-       int size;
-       if (gfds_size_max / 2 < n_gfds)
-         memory_full (SIZE_MAX);
-       size = 2 * n_gfds;
-       gfds_size = 0;
         xfree (gfds);
-       gfds = xmalloc (sizeof *gfds * size);
-       gfds_size = size;
+       gfds = xpalloc (0, &gfds_size, n_gfds - gfds_size, INT_MAX,
+                       sizeof *gfds);
       }
 
     n_gfds = g_main_context_query (context,
index 7c2cd586b093a10fadab07fc5f9353f820f9b194..63f06738b98441f440ad36307bc47fc1044e5373 100644 (file)
@@ -204,10 +204,7 @@ magic_file_p (const char *string, EMACS_INT string_len, const char *class,
       if (path_size - path_len <= next_len)
        {
          if (min (PTRDIFF_MAX, SIZE_MAX) / 2 - 1 - path_len < next_len)
-           {
-             xfree (path);
-             memory_full (SIZE_MAX);
-           }
+           memory_full (SIZE_MAX);
          path_size = (path_len + next_len + 1) * 2;
          path = (char *) xrealloc (path, path_size);
        }
index d8b7b077a8cfe2bf36905ee8474b92508abe57d4..5c2e12c5ef1c4624b44817b8f909bd14400fb7cc 100644 (file)
@@ -1503,17 +1503,9 @@ receive_incremental_selection (Display *display, Window window, Atom property,
       UNBLOCK_INPUT;
 
       if (*size_bytes_ret - offset < tmp_size_bytes)
-       {
-         ptrdiff_t size;
-         if (min (PTRDIFF_MAX, SIZE_MAX) - offset < tmp_size_bytes)
-           {
-             xfree (tmp_data);
-             memory_full (SIZE_MAX);
-           }
-         size = offset + tmp_size_bytes;
-         *data_ret = (unsigned char *) xrealloc (*data_ret, size);
-         *size_bytes_ret = size;
-       }
+       *data_ret = xpalloc (*data_ret, size_bytes_ret,
+                            tmp_size_bytes - (*size_bytes_ret - offset),
+                            -1, 1);
 
       memcpy ((*data_ret) + offset, tmp_data, tmp_size_bytes);
       offset += tmp_size_bytes;
@@ -1806,14 +1798,12 @@ lisp_data_to_selection_data (Display *display, Lisp_Object obj,
       if (SYMBOLP (XVECTOR (obj)->contents [0]))
        /* This vector is an ATOM set */
        {
-         if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (Atom) < size)
-           memory_full (SIZE_MAX);
          if (NILP (type)) type = QATOM;
          for (i = 0; i < size; i++)
            if (!SYMBOLP (XVECTOR (obj)->contents [i]))
              signal_error ("All elements of selection vector must have same type", obj);
 
-         *data_ret = (unsigned char *) xmalloc (size * sizeof (Atom));
+         *data_ret = xnmalloc (size, sizeof (Atom));
          *format_ret = 32;
          *size_ret = size;
          for (i = 0; i < size; i++)
@@ -1824,7 +1814,7 @@ lisp_data_to_selection_data (Display *display, Lisp_Object obj,
        /* This vector is an INTEGER set, or something like it */
        {
          int format = 16;
-          int data_size = 2;
+         int data_size = sizeof (short);
          if (NILP (type)) type = QINTEGER;
          for (i = 0; i < size; i++)
            if (X_USHRT_MAX
@@ -1836,9 +1826,7 @@ lisp_data_to_selection_data (Display *display, Lisp_Object obj,
                data_size = sizeof (long);
                format = 32;
              }
-         if (min (PTRDIFF_MAX, SIZE_MAX) / data_size < size)
-           memory_full (SIZE_MAX);
-         *data_ret = (unsigned char *) xmalloc (size * data_size);
+         *data_ret = xnmalloc (size, data_size);
          *format_ret = format;
          *size_ret = size;
          for (i = 0; i < size; i++)
index 217087dbae739b84a1078e35477f519b2d520149..55daec73307116d12f0d5dc21567075205771bfe 100644 (file)
@@ -223,12 +223,11 @@ smc_save_yourself_CB (SmcConn smcConn,
   props[props_idx]->name = xstrdup (SmRestartCommand);
   props[props_idx]->type = xstrdup (SmLISTofARRAY8);
   /* /path/to/emacs, --smid=xxx --no-splash --chdir=dir ... */
-  if (min (INT_MAX, min (PTRDIFF_MAX, SIZE_MAX) / sizeof *vp) - 3
-      < initial_argc)
+  if (INT_MAX - 3 < initial_argc)
     memory_full (SIZE_MAX);
   i = 3 + initial_argc;
   props[props_idx]->num_vals = i;
-  vp = (SmPropValue *) xmalloc (i * sizeof(*vp));
+  vp = xnmalloc (i, sizeof *vp);
   props[props_idx]->vals = vp;
   props[props_idx]->vals[vp_idx].length = strlen (emacs_program);
   props[props_idx]->vals[vp_idx++].value = emacs_program;
index 4ef0061dba6ff62b927658f3d6199ceb5cc911a2..2c973d6b967741bc18f5801f69cb040fdab9067e 100644 (file)
@@ -1628,11 +1628,8 @@ x_color_cells (Display *dpy, int *ncells)
       int ncolor_cells = XDisplayCells (dpy, XScreenNumberOfScreen (screen));
       int i;
 
-      if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (XColor) < ncolor_cells)
-       memory_full (SIZE_MAX);
-      dpyinfo->color_cells
-       = (XColor *) xmalloc (ncolor_cells
-                             * sizeof *dpyinfo->color_cells);
+      dpyinfo->color_cells = xnmalloc (ncolor_cells,
+                                      sizeof *dpyinfo->color_cells);
       dpyinfo->ncolor_cells = ncolor_cells;
 
       for (i = 0; i < ncolor_cells; ++i)
@@ -4228,20 +4225,15 @@ x_send_scroll_bar_event (Lisp_Object window, int part, int portion, int whole)
 
   if (i == scroll_bar_windows_size)
     {
-      ptrdiff_t new_size, old_nbytes, nbytes;
-      /* Check the 32-bit XClientMessageEvent limit, as well as the
-        usual ptrdiff_t/size_t limit.  */
-      if (min (0x7fffffff,
-              min (PTRDIFF_MAX, SIZE_MAX) / sizeof *scroll_bar_windows / 2)
-         < scroll_bar_windows_size)
-       memory_full (SIZE_MAX);
-      new_size = max (10, 2 * scroll_bar_windows_size);
-      nbytes = new_size * sizeof *scroll_bar_windows;
-      old_nbytes = scroll_bar_windows_size * sizeof *scroll_bar_windows;
-      scroll_bar_windows = (struct window **) xrealloc (scroll_bar_windows,
-                                                       nbytes);
+      ptrdiff_t old_nbytes =
+       scroll_bar_windows_size * sizeof *scroll_bar_windows;
+      ptrdiff_t nbytes;
+      enum { XClientMessageEvent_MAX = 0x7fffffff };
+      scroll_bar_windows =
+       xpalloc (scroll_bar_windows, &scroll_bar_windows_size, 1,
+                XClientMessageEvent_MAX, sizeof *scroll_bar_windows);
+      nbytes = scroll_bar_windows_size * sizeof *scroll_bar_windows;
       memset (&scroll_bar_windows[i], 0, nbytes - old_nbytes);
-      scroll_bar_windows_size = new_size;
     }
 
   scroll_bar_windows[i] = w;
@@ -5824,6 +5816,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
   struct coding_system coding;
   XEvent event = *eventptr;
   Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight;
+  USE_SAFE_ALLOCA;
 
   *finish = X_EVENT_NORMAL;
 
@@ -6530,11 +6523,6 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
            if (nchars < nbytes)
              {
                /* Decode the input data.  */
-               ptrdiff_t require;
-
-               if (min (PTRDIFF_MAX, SIZE_MAX) / MAX_MULTIBYTE_LENGTH
-                   < nbytes)
-                 memory_full (SIZE_MAX);
 
                /* The input should be decoded with `coding_system'
                   which depends on which X*LookupString function
@@ -6547,9 +6535,9 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
                   gives us composition information.  */
                coding.common_flags &= ~CODING_ANNOTATION_MASK;
 
-               require = MAX_MULTIBYTE_LENGTH * nbytes;
-               coding.destination = alloca (require);
-               coding.dst_bytes = require;
+               SAFE_NALLOCA (coding.destination, MAX_MULTIBYTE_LENGTH,
+                             nbytes);
+               coding.dst_bytes = MAX_MULTIBYTE_LENGTH * nbytes;
                coding.mode |= CODING_MODE_LAST_BLOCK;
                decode_coding_c_string (&coding, copy_bufptr, nbytes, Qnil);
                nbytes = coding.produced;
@@ -7008,6 +6996,7 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr,
       count++;
     }
 
+  SAFE_FREE ();
   *eventptr = event;
   return count;
 }