aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert <[email protected]>2011-08-04 19:15:35 -0700
committerPaul Eggert <[email protected]>2011-08-04 19:15:35 -0700
commit0065d05491ce5981ea20896bb26d21dcd31e6769 (patch)
tree13240167319d4a99ab5eacae4a883258eb2d28de /src
parent18ab493650d648ab8dca651ea2698861f926e895 (diff)
Adjust in response to jan.h.d's comments.
See, for example <http://debbugs.gnu.org/cgi/bugreport.cgi?bug=9196#26>.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog83
-rw-r--r--src/alloc.c88
-rw-r--r--src/bidi.c11
-rw-r--r--src/buffer.c64
-rw-r--r--src/callproc.c10
-rw-r--r--src/ccl.c40
-rw-r--r--src/character.c4
-rw-r--r--src/charset.c66
-rw-r--r--src/cmds.c2
-rw-r--r--src/composite.c39
-rw-r--r--src/composite.h2
-rw-r--r--src/dispextern.h5
-rw-r--r--src/dispnew.c99
-rw-r--r--src/doc.c12
-rw-r--r--src/emacs.c38
-rw-r--r--src/eval.c3
-rw-r--r--src/fns.c7
-rw-r--r--src/ftfont.c33
-rw-r--r--src/gtkutil.c8
-rw-r--r--src/image.c6
-rw-r--r--src/indent.c2
-rw-r--r--src/lisp.h20
-rw-r--r--src/minibuf.c5
-rw-r--r--src/nsterm.m16
-rw-r--r--src/process.c18
-rw-r--r--src/region-cache.c89
-rw-r--r--src/region-cache.h12
-rw-r--r--src/scroll.c15
-rw-r--r--src/search.c69
-rw-r--r--src/term.c43
-rw-r--r--src/termcap.c9
-rw-r--r--src/tparam.c17
-rw-r--r--src/xdisp.c13
-rw-r--r--src/xfaces.c31
-rw-r--r--src/xfns.c8
-rw-r--r--src/xgselect.c13
-rw-r--r--src/xrdb.c5
-rw-r--r--src/xselect.c24
-rw-r--r--src/xsmfns.c5
-rw-r--r--src/xterm.c41
40 files changed, 498 insertions, 577 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index a88e2e8e3c..b525d83e28 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,7 +1,48 @@
-2011-07-29 Paul Eggert <[email protected]>
+2011-08-05 Paul Eggert <[email protected]>
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.
@@ -10,12 +51,21 @@
(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.
@@ -55,7 +105,10 @@
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.
@@ -119,9 +172,6 @@
* 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.
@@ -161,25 +211,29 @@
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.
@@ -229,10 +283,11 @@
* 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).
diff --git a/src/alloc.c b/src/alloc.c
index b96fc1f064..a1af0df11f 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -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 *
diff --git a/src/bidi.c b/src/bidi.c
index a1e5721f35..27a6645dff 100644
--- a/src/bidi.c
+++ b/src/bidi.c
@@ -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);
}
}
diff --git a/src/buffer.c b/src/buffer.c
index cacc8a4133..b61d083c3e 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -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;)
{
diff --git a/src/callproc.c b/src/callproc.c
index 993d943e15..4f6d363d5e 100644
--- a/src/callproc.c
+++ b/src/callproc.c
@@ -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
diff --git a/src/ccl.c b/src/ccl.c
index 0a9b3d9070..dc0adae687 100644
--- 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++)
diff --git a/src/character.c b/src/character.c
index 50b5b25287..fb9b8a9b93 100644
--- a/src/character.c
+++ b/src/character.c
@@ -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++)
diff --git a/src/charset.c b/src/charset.c
index 852aeb19bc..6967b9df61 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -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);
diff --git a/src/cmds.c b/src/cmds.c
index f49cfc221b..2feaf313f2 100644
--- a/src/cmds.c
+++ b/src/cmds.c
@@ -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);
diff --git a/src/composite.c b/src/composite.c
index 4ae1d6ebb6..738fcd3774 100644
--- a/src/composite.c
+++ b/src/composite.c
@@ -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)
diff --git a/src/composite.h b/src/composite.h
index c30c683279..c57e2a0e9b 100644
--- a/src/composite.h
+++ b/src/composite.h
@@ -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;
diff --git a/src/dispextern.h b/src/dispextern.h
index 70f426f95a..c43eeb5560 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -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. */
diff --git a/src/dispnew.c b/src/dispnew.c
index 4cc101d98b..fde9be6bf5 100644
--- a/src/dispnew.c
+++ b/src/dispnew.c
@@ -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;
}
diff --git a/src/doc.c b/src/doc.c
index bd1831dde0..eb8ff3c252 100644
--- 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));
diff --git a/src/emacs.c b/src/emacs.c
index 4de567a558..e4c42c3e19 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -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++)
diff --git a/src/eval.c b/src/eval.c
index bcb77574fe..94039b31e1 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -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;
}
diff --git a/src/fns.c b/src/fns.c
index e5538d6acb..a3af6b8c15 100644
--- 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++)
{
diff --git a/src/ftfont.c b/src/ftfont.c
index 551006eef9..5b95e2b2f0 100644
--- a/src/ftfont.c
+++ b/src/ftfont.c
@@ -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;
diff --git a/src/gtkutil.c b/src/gtkutil.c
index f56e888e68..2492ce620b 100644
--- a/src/gtkutil.c
+++ b/src/gtkutil.c
@@ -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;
diff --git a/src/image.c b/src/image.c
index d2a71637fe..bf7daa24da 100644
--- a/src/image.c
+++ b/src/image.c
@@ -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)
{
diff --git a/src/indent.c b/src/indent.c
index 8a2117751a..37873351aa 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -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,
diff --git a/src/lisp.h b/src/lisp.h
index 267bfe1b21..83cc680b7e 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -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() \
diff --git a/src/minibuf.c b/src/minibuf.c
index 30082af903..eb564a10ec 100644
--- a/src/minibuf.c
+++ b/src/minibuf.c
@@ -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);
}
diff --git a/src/nsterm.m b/src/nsterm.m
index 2ce996dc82..484e8847dc 100644
--- a/src/nsterm.m
+++ b/src/nsterm.m
@@ -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++;
}
diff --git a/src/process.c b/src/process.c
index 31359a1f1f..f2c2bfd81c 100644
--- a/src/process.c
+++ b/src/process.c
@@ -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))
diff --git a/src/region-cache.c b/src/region-cache.c
index e6cec96171..ed7a07a670 100644
--- a/src/region-cache.c
+++ b/src/region-cache.c
@@ -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));
}
}
diff --git a/src/region-cache.h b/src/region-cache.h
index ea767ed0dc..8e1be71677 100644
--- a/src/region-cache.h
+++ b/src/region-cache.h
@@ -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);
diff --git a/src/scroll.c b/src/scroll.c
index 9184919f0c..05f6fdf85f 100644
--- a/src/scroll.c
+++ b/src/scroll.c
@@ -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,
diff --git a/src/search.c b/src/search.c
index 79ef8b046d..d892792cba 100644
--- a/src/search.c
+++ b/src/search.c
@@ -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++)
diff --git a/src/term.c b/src/term.c
index bc6fa8f80f..f3bf3a947c 100644
--- a/src/term.c
+++ b/src/term.c
@@ -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))
diff --git a/src/termcap.c b/src/termcap.c
index 791c593c06..6f24817fa7 100644
--- a/src/termcap.c
+++ b/src/termcap.c
@@ -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;
}
diff --git a/src/tparam.c b/src/tparam.c
index 06cec87315..ac21667d65 100644
--- a/src/tparam.c
+++ b/src/tparam.c
@@ -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;
}
diff --git a/src/xdisp.c b/src/xdisp.c
index d44e677eeb..b64a2c0cf6 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -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;
}
diff --git a/src/xfaces.c b/src/xfaces.c
index 352fdb4b08..53b30a5c1c 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -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++;
}
diff --git a/src/xfns.c b/src/xfns.c
index 1169acb3cf..9a3d5fcda8 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -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);
}
diff --git a/src/xgselect.c b/src/xgselect.c
index d184461007..339ec47511 100644
--- a/src/xgselect.c
+++ b/src/xgselect.c
@@ -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,
diff --git a/src/xrdb.c b/src/xrdb.c
index 7c2cd586b0..63f06738b9 100644
--- a/src/xrdb.c
+++ b/src/xrdb.c
@@ -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);
}
diff --git a/src/xselect.c b/src/xselect.c
index d8b7b077a8..5c2e12c5ef 100644
--- a/src/xselect.c
+++ b/src/xselect.c
@@ -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++)
diff --git a/src/xsmfns.c b/src/xsmfns.c
index 217087dbae..55daec7330 100644
--- a/src/xsmfns.c
+++ b/src/xsmfns.c
@@ -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;
diff --git a/src/xterm.c b/src/xterm.c
index 4ef0061dba..2c973d6b96 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -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;
}