See, for example <http://debbugs.gnu.org/cgi/bugreport.cgi?bug=9196#26>.
-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).
#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. */
}
+/* 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 *
/* 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 =
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);
}
}
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;
{
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;
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;
{
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;
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
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;
else
nbytes = SBYTES (str);
+ if (INT_ADD_OVERFLOW (ssl->bytes, nbytes))
+ memory_full (SIZE_MAX);
ssl->bytes += nbytes;
if (STRINGP (str2))
else
nbytes = SBYTES (str2);
+ if (INT_ADD_OVERFLOW (ssl->bytes, nbytes))
+ memory_full (SIZE_MAX);
ssl->bytes += nbytes;
}
}
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;)
{
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);
{
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
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);
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
#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");
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
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++)
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++)
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++)
/* 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;
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;
{
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,
(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;
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);
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");
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);
{
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);
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
/* 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;
? (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. */
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)
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;
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. */
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. */
/* 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;
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
|| 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
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. */
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)));
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.
{
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;
}
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));
/* 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)
{
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++)
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;
}
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++)
{
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;
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)
{
}
}
- 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++)
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;
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;
#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)
{
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,
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 *);
} \
} 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() \
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);
}
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++;
}
{
struct ifconf ifconf;
struct ifreq *ifreqs = NULL;
- int ifaces = 0;
+ ptrdiff_t ifaces = 0;
int buf_size, s;
Lisp_Object res;
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))
revalidate_region_cache to see how this helps. */
struct boundary {
- EMACS_INT pos;
+ ptrdiff_t pos;
int value;
};
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
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. */
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;
/* 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)
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
/* 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. */
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
/* 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 ();
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,
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.
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. */
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);
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))
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);
}
{
- 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)
{
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) ? '-'
: (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));
}
}
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.
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.
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);
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,
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))
/* 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))
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
{
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)
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]);
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)
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++)
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;
}
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)
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));
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))
{
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;
}
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;
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;
}
}
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;
}
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;
}
/* 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). */
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));
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++;
}
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;
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);
}
#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,
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,
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);
}
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;
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++)
/* 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
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++)
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;
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)
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;
struct coding_system coding;
XEvent event = *eventptr;
Mouse_HLInfo *hlinfo = &dpyinfo->mouse_highlight;
+ USE_SAFE_ALLOCA;
*finish = X_EVENT_NORMAL;
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
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;
count++;
}
+ SAFE_FREE ();
*eventptr = event;
return count;
}