diff options
| author | Paul Eggert | 2015-11-08 22:47:01 -0800 |
|---|---|---|
| committer | Paul Eggert | 2015-11-08 22:48:28 -0800 |
| commit | 1087305574fd61256d66eb0c995f8bb74bd91afe (patch) | |
| tree | 9f0052e41a56c785575727931ff4abb8e7dfa7e0 /src | |
| parent | bcca6a2a028d05af3cb5b31a5a2c997f3f1f1d31 (diff) | |
| download | emacs-1087305574fd61256d66eb0c995f8bb74bd91afe.tar.gz emacs-1087305574fd61256d66eb0c995f8bb74bd91afe.zip | |
Use INT_ADD_WRAPV etc. to check integer overflow
* src/alloc.c (xnmalloc, xnrealloc, xpalloc, Fmake_string):
* src/buffer.c (record_overlay_string, overlay_strings):
* src/casefiddle.c (casify_object):
* src/ccl.c (Fccl_execute_on_string):
* src/character.c (char_width, c_string_width, lisp_string_width)
(count_size_as_multibyte, string_escape_byte8):
* src/coding.c (coding_alloc_by_realloc, produce_chars):
* src/data.c (arith_driver):
* src/dispnew.c (realloc_glyph_pool, init_display):
* src/editfns.c (styled_format):
* src/fns.c (Ffillarray):
* src/ftfont.c (ftfont_shape_by_flt):
* src/gnutls.c (gnutls_hex_string):
* src/gtkutil.c (get_utf8_string):
* src/image.c (x_to_xcolors, x_detect_edges, png_load_body):
* src/keymap.c (Fkey_description):
* src/lisp.h (SAFE_ALLOCA_LISP):
* src/term.c (encode_terminal_code):
* src/tparam.c (tparam1):
* src/xselect.c (x_property_data_to_lisp):
* src/xsmfns.c (smc_save_yourself_CB):
* src/xterm.c (x_term_init):
When checking for integer overflow, prefer INT_MULTIPLY_WRAPV to
more-complicated code involving division and/or
INT_MULTIPLY_OVERFLOW, and similarly for INT_ADD_WRAPV and
subtraction and/or INT_ADD_OVERFLOW.
* src/casefiddle.c (casify_object): Simplify multibyte size check.
* src/character.c: Remove some obsolete ‘#ifdef emacs’s.
* src/data.c (arith_driver): Also check for division overflow,
as that’s now possible given that the accumulator can now contain
any Emacs integer.
* src/lisp.h (lisp_word_count): Remove; no longer used.
Diffstat (limited to 'src')
| -rw-r--r-- | src/alloc.c | 55 | ||||
| -rw-r--r-- | src/buffer.c | 11 | ||||
| -rw-r--r-- | src/casefiddle.c | 8 | ||||
| -rw-r--r-- | src/ccl.c | 8 | ||||
| -rw-r--r-- | src/character.c | 63 | ||||
| -rw-r--r-- | src/coding.c | 21 | ||||
| -rw-r--r-- | src/data.c | 31 | ||||
| -rw-r--r-- | src/dispnew.c | 12 | ||||
| -rw-r--r-- | src/editfns.c | 7 | ||||
| -rw-r--r-- | src/fns.c | 4 | ||||
| -rw-r--r-- | src/ftfont.c | 18 | ||||
| -rw-r--r-- | src/gnutls.c | 7 | ||||
| -rw-r--r-- | src/gtkutil.c | 7 | ||||
| -rw-r--r-- | src/image.c | 20 | ||||
| -rw-r--r-- | src/keymap.c | 5 | ||||
| -rw-r--r-- | src/lisp.h | 32 | ||||
| -rw-r--r-- | src/term.c | 4 | ||||
| -rw-r--r-- | src/tparam.c | 4 | ||||
| -rw-r--r-- | src/xselect.c | 5 | ||||
| -rw-r--r-- | src/xsmfns.c | 3 | ||||
| -rw-r--r-- | src/xterm.c | 9 |
21 files changed, 150 insertions, 184 deletions
diff --git a/src/alloc.c b/src/alloc.c index 8f94d2b6097..60751bcfe2b 100644 --- a/src/alloc.c +++ b/src/alloc.c | |||
| @@ -802,9 +802,10 @@ void * | |||
| 802 | xnmalloc (ptrdiff_t nitems, ptrdiff_t item_size) | 802 | xnmalloc (ptrdiff_t nitems, ptrdiff_t item_size) |
| 803 | { | 803 | { |
| 804 | eassert (0 <= nitems && 0 < item_size); | 804 | eassert (0 <= nitems && 0 < item_size); |
| 805 | if (min (PTRDIFF_MAX, SIZE_MAX) / item_size < nitems) | 805 | ptrdiff_t nbytes; |
| 806 | if (INT_MULTIPLY_WRAPV (nitems, item_size, &nbytes) || SIZE_MAX < nbytes) | ||
| 806 | memory_full (SIZE_MAX); | 807 | memory_full (SIZE_MAX); |
| 807 | return xmalloc (nitems * item_size); | 808 | return xmalloc (nbytes); |
| 808 | } | 809 | } |
| 809 | 810 | ||
| 810 | 811 | ||
| @@ -815,9 +816,10 @@ void * | |||
| 815 | xnrealloc (void *pa, ptrdiff_t nitems, ptrdiff_t item_size) | 816 | xnrealloc (void *pa, ptrdiff_t nitems, ptrdiff_t item_size) |
| 816 | { | 817 | { |
| 817 | eassert (0 <= nitems && 0 < item_size); | 818 | eassert (0 <= nitems && 0 < item_size); |
| 818 | if (min (PTRDIFF_MAX, SIZE_MAX) / item_size < nitems) | 819 | ptrdiff_t nbytes; |
| 820 | if (INT_MULTIPLY_WRAPV (nitems, item_size, &nbytes) || SIZE_MAX < nbytes) | ||
| 819 | memory_full (SIZE_MAX); | 821 | memory_full (SIZE_MAX); |
| 820 | return xrealloc (pa, nitems * item_size); | 822 | return xrealloc (pa, nbytes); |
| 821 | } | 823 | } |
| 822 | 824 | ||
| 823 | 825 | ||
| @@ -848,33 +850,43 @@ void * | |||
| 848 | xpalloc (void *pa, ptrdiff_t *nitems, ptrdiff_t nitems_incr_min, | 850 | xpalloc (void *pa, ptrdiff_t *nitems, ptrdiff_t nitems_incr_min, |
| 849 | ptrdiff_t nitems_max, ptrdiff_t item_size) | 851 | ptrdiff_t nitems_max, ptrdiff_t item_size) |
| 850 | { | 852 | { |
| 853 | ptrdiff_t n0 = *nitems; | ||
| 854 | eassume (0 < item_size && 0 < nitems_incr_min && 0 <= n0 && -1 <= nitems_max); | ||
| 855 | |||
| 851 | /* The approximate size to use for initial small allocation | 856 | /* The approximate size to use for initial small allocation |
| 852 | requests. This is the largest "small" request for the GNU C | 857 | requests. This is the largest "small" request for the GNU C |
| 853 | library malloc. */ | 858 | library malloc. */ |
| 854 | enum { DEFAULT_MXFAST = 64 * sizeof (size_t) / 4 }; | 859 | enum { DEFAULT_MXFAST = 64 * sizeof (size_t) / 4 }; |
| 855 | 860 | ||
| 856 | /* If the array is tiny, grow it to about (but no greater than) | 861 | /* If the array is tiny, grow it to about (but no greater than) |
| 857 | DEFAULT_MXFAST bytes. Otherwise, grow it by about 50%. */ | 862 | DEFAULT_MXFAST bytes. Otherwise, grow it by about 50%. |
| 858 | ptrdiff_t n = *nitems; | 863 | Adjust the growth according to three constraints: NITEMS_INCR_MIN, |
| 859 | ptrdiff_t tiny_max = DEFAULT_MXFAST / item_size - n; | ||
| 860 | ptrdiff_t half_again = n >> 1; | ||
| 861 | ptrdiff_t incr_estimate = max (tiny_max, half_again); | ||
| 862 | |||
| 863 | /* Adjust the increment according to three constraints: NITEMS_INCR_MIN, | ||
| 864 | NITEMS_MAX, and what the C language can represent safely. */ | 864 | NITEMS_MAX, and what the C language can represent safely. */ |
| 865 | ptrdiff_t C_language_max = min (PTRDIFF_MAX, SIZE_MAX) / item_size; | ||
| 866 | ptrdiff_t n_max = (0 <= nitems_max && nitems_max < C_language_max | ||
| 867 | ? nitems_max : C_language_max); | ||
| 868 | ptrdiff_t nitems_incr_max = n_max - n; | ||
| 869 | ptrdiff_t incr = max (nitems_incr_min, min (incr_estimate, nitems_incr_max)); | ||
| 870 | 865 | ||
| 871 | eassert (0 < item_size && 0 < nitems_incr_min && 0 <= n && -1 <= nitems_max); | 866 | ptrdiff_t n, nbytes; |
| 867 | if (INT_ADD_WRAPV (n0, n0 >> 1, &n)) | ||
| 868 | n = PTRDIFF_MAX; | ||
| 869 | if (0 <= nitems_max && nitems_max < n) | ||
| 870 | n = nitems_max; | ||
| 871 | |||
| 872 | ptrdiff_t adjusted_nbytes | ||
| 873 | = ((INT_MULTIPLY_WRAPV (n, item_size, &nbytes) || SIZE_MAX < nbytes) | ||
| 874 | ? min (PTRDIFF_MAX, SIZE_MAX) | ||
| 875 | : nbytes < DEFAULT_MXFAST ? DEFAULT_MXFAST : 0); | ||
| 876 | if (adjusted_nbytes) | ||
| 877 | { | ||
| 878 | n = adjusted_nbytes / item_size; | ||
| 879 | nbytes = adjusted_nbytes - adjusted_nbytes % item_size; | ||
| 880 | } | ||
| 881 | |||
| 872 | if (! pa) | 882 | if (! pa) |
| 873 | *nitems = 0; | 883 | *nitems = 0; |
| 874 | if (nitems_incr_max < incr) | 884 | if (n - n0 < nitems_incr_min |
| 885 | && (INT_ADD_WRAPV (n0, nitems_incr_min, &n) | ||
| 886 | || (0 <= nitems_max && nitems_max < n) | ||
| 887 | || INT_MULTIPLY_WRAPV (n, item_size, &nbytes))) | ||
| 875 | memory_full (SIZE_MAX); | 888 | memory_full (SIZE_MAX); |
| 876 | n += incr; | 889 | pa = xrealloc (pa, nbytes); |
| 877 | pa = xrealloc (pa, n * item_size); | ||
| 878 | *nitems = n; | 890 | *nitems = n; |
| 879 | return pa; | 891 | return pa; |
| 880 | } | 892 | } |
| @@ -2104,9 +2116,8 @@ INIT must be an integer that represents a character. */) | |||
| 2104 | EMACS_INT string_len = XINT (length); | 2116 | EMACS_INT string_len = XINT (length); |
| 2105 | unsigned char *p, *beg, *end; | 2117 | unsigned char *p, *beg, *end; |
| 2106 | 2118 | ||
| 2107 | if (string_len > STRING_BYTES_MAX / len) | 2119 | if (INT_MULTIPLY_WRAPV (len, string_len, &nbytes)) |
| 2108 | string_overflow (); | 2120 | string_overflow (); |
| 2109 | nbytes = len * string_len; | ||
| 2110 | val = make_uninit_multibyte_string (string_len, nbytes); | 2121 | val = make_uninit_multibyte_string (string_len, nbytes); |
| 2111 | for (beg = SDATA (val), p = beg, end = beg + nbytes; p < end; p += len) | 2122 | for (beg = SDATA (val), p = beg, end = beg + nbytes; p < end; p += len) |
| 2112 | { | 2123 | { |
diff --git a/src/buffer.c b/src/buffer.c index c0179c7584e..ab91aaa4e81 100644 --- a/src/buffer.c +++ b/src/buffer.c | |||
| @@ -3245,9 +3245,9 @@ record_overlay_string (struct sortstrlist *ssl, Lisp_Object str, | |||
| 3245 | else | 3245 | else |
| 3246 | nbytes = SBYTES (str); | 3246 | nbytes = SBYTES (str); |
| 3247 | 3247 | ||
| 3248 | if (INT_ADD_OVERFLOW (ssl->bytes, nbytes)) | 3248 | if (INT_ADD_WRAPV (ssl->bytes, nbytes, &nbytes)) |
| 3249 | memory_full (SIZE_MAX); | 3249 | memory_full (SIZE_MAX); |
| 3250 | ssl->bytes += nbytes; | 3250 | ssl->bytes = nbytes; |
| 3251 | 3251 | ||
| 3252 | if (STRINGP (str2)) | 3252 | if (STRINGP (str2)) |
| 3253 | { | 3253 | { |
| @@ -3259,9 +3259,9 @@ record_overlay_string (struct sortstrlist *ssl, Lisp_Object str, | |||
| 3259 | else | 3259 | else |
| 3260 | nbytes = SBYTES (str2); | 3260 | nbytes = SBYTES (str2); |
| 3261 | 3261 | ||
| 3262 | if (INT_ADD_OVERFLOW (ssl->bytes, nbytes)) | 3262 | if (INT_ADD_WRAPV (ssl->bytes, nbytes, &nbytes)) |
| 3263 | memory_full (SIZE_MAX); | 3263 | memory_full (SIZE_MAX); |
| 3264 | ssl->bytes += nbytes; | 3264 | ssl->bytes = nbytes; |
| 3265 | } | 3265 | } |
| 3266 | } | 3266 | } |
| 3267 | 3267 | ||
| @@ -3357,9 +3357,8 @@ overlay_strings (ptrdiff_t pos, struct window *w, unsigned char **pstr) | |||
| 3357 | unsigned char *p; | 3357 | unsigned char *p; |
| 3358 | ptrdiff_t total; | 3358 | ptrdiff_t total; |
| 3359 | 3359 | ||
| 3360 | if (INT_ADD_OVERFLOW (overlay_heads.bytes, overlay_tails.bytes)) | 3360 | if (INT_ADD_WRAPV (overlay_heads.bytes, overlay_tails.bytes, &total)) |
| 3361 | memory_full (SIZE_MAX); | 3361 | memory_full (SIZE_MAX); |
| 3362 | total = overlay_heads.bytes + overlay_tails.bytes; | ||
| 3363 | if (total > overlay_str_len) | 3362 | if (total > overlay_str_len) |
| 3364 | overlay_str_buf = xpalloc (overlay_str_buf, &overlay_str_len, | 3363 | overlay_str_buf = xpalloc (overlay_str_buf, &overlay_str_len, |
| 3365 | total - overlay_str_len, -1, 1); | 3364 | total - overlay_str_len, -1, 1); |
diff --git a/src/casefiddle.c b/src/casefiddle.c index 8755353240a..b94ea8e212e 100644 --- a/src/casefiddle.c +++ b/src/casefiddle.c | |||
| @@ -114,15 +114,15 @@ casify_object (enum case_action flag, Lisp_Object obj) | |||
| 114 | ptrdiff_t i, i_byte, size = SCHARS (obj); | 114 | ptrdiff_t i, i_byte, size = SCHARS (obj); |
| 115 | int len; | 115 | int len; |
| 116 | USE_SAFE_ALLOCA; | 116 | USE_SAFE_ALLOCA; |
| 117 | ptrdiff_t o_size = (size < STRING_BYTES_BOUND / MAX_MULTIBYTE_LENGTH | 117 | ptrdiff_t o_size; |
| 118 | ? size * MAX_MULTIBYTE_LENGTH | 118 | if (INT_MULTIPLY_WRAPV (size, MAX_MULTIBYTE_LENGTH, &o_size)) |
| 119 | : STRING_BYTES_BOUND); | 119 | o_size = PTRDIFF_MAX; |
| 120 | unsigned char *dst = SAFE_ALLOCA (o_size); | 120 | unsigned char *dst = SAFE_ALLOCA (o_size); |
| 121 | unsigned char *o = dst; | 121 | unsigned char *o = dst; |
| 122 | 122 | ||
| 123 | for (i = i_byte = 0; i < size; i++, i_byte += len) | 123 | for (i = i_byte = 0; i < size; i++, i_byte += len) |
| 124 | { | 124 | { |
| 125 | if (o_size - (o - dst) < MAX_MULTIBYTE_LENGTH) | 125 | if (o_size - MAX_MULTIBYTE_LENGTH < o - dst) |
| 126 | string_overflow (); | 126 | string_overflow (); |
| 127 | c = STRING_CHAR_AND_LENGTH (SDATA (obj) + i_byte, len); | 127 | c = STRING_CHAR_AND_LENGTH (SDATA (obj) + i_byte, len); |
| 128 | if (inword && flag != CASE_CAPITALIZE_UP) | 128 | if (inword && flag != CASE_CAPITALIZE_UP) |
| @@ -2071,12 +2071,10 @@ usage: (ccl-execute-on-string CCL-PROGRAM STATUS STRING &optional CONTINUE UNIBY | |||
| 2071 | } | 2071 | } |
| 2072 | 2072 | ||
| 2073 | buf_magnification = ccl.buf_magnification ? ccl.buf_magnification : 1; | 2073 | buf_magnification = ccl.buf_magnification ? ccl.buf_magnification : 1; |
| 2074 | 2074 | outbufsize = str_bytes; | |
| 2075 | if ((min (PTRDIFF_MAX, SIZE_MAX) - 256) / buf_magnification < str_bytes) | 2075 | if (INT_MULTIPLY_WRAPV (buf_magnification, outbufsize, &outbufsize) |
| 2076 | || INT_ADD_WRAPV (256, outbufsize, &outbufsize)) | ||
| 2076 | memory_full (SIZE_MAX); | 2077 | memory_full (SIZE_MAX); |
| 2077 | outbufsize = (ccl.buf_magnification | ||
| 2078 | ? str_bytes * ccl.buf_magnification + 256 | ||
| 2079 | : str_bytes + 256); | ||
| 2080 | outp = outbuf = xmalloc (outbufsize); | 2078 | outp = outbuf = xmalloc (outbufsize); |
| 2081 | 2079 | ||
| 2082 | consumed_chars = consumed_bytes = 0; | 2080 | consumed_chars = consumed_bytes = 0; |
diff --git a/src/character.c b/src/character.c index 3e2bf1e70c2..bc2fa4a12da 100644 --- a/src/character.c +++ b/src/character.c | |||
| @@ -25,14 +25,10 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 25 | /* At first, see the document in `character.h' to understand the code | 25 | /* At first, see the document in `character.h' to understand the code |
| 26 | in this file. */ | 26 | in this file. */ |
| 27 | 27 | ||
| 28 | #ifdef emacs | ||
| 29 | #include <config.h> | 28 | #include <config.h> |
| 30 | #endif | ||
| 31 | 29 | ||
| 32 | #include <stdio.h> | 30 | #include <stdio.h> |
| 33 | 31 | ||
| 34 | #ifdef emacs | ||
| 35 | |||
| 36 | #include <sys/types.h> | 32 | #include <sys/types.h> |
| 37 | #include <intprops.h> | 33 | #include <intprops.h> |
| 38 | #include "lisp.h" | 34 | #include "lisp.h" |
| @@ -41,12 +37,6 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */ | |||
| 41 | #include "composite.h" | 37 | #include "composite.h" |
| 42 | #include "disptab.h" | 38 | #include "disptab.h" |
| 43 | 39 | ||
| 44 | #else /* not emacs */ | ||
| 45 | |||
| 46 | #include "mulelib.h" | ||
| 47 | |||
| 48 | #endif /* emacs */ | ||
| 49 | |||
| 50 | /* Char-table of information about which character to unify to which | 40 | /* Char-table of information about which character to unify to which |
| 51 | Unicode character. Mainly used by the macro MAYBE_UNIFY_CHAR. */ | 41 | Unicode character. Mainly used by the macro MAYBE_UNIFY_CHAR. */ |
| 52 | Lisp_Object Vchar_unify_table; | 42 | Lisp_Object Vchar_unify_table; |
| @@ -302,9 +292,8 @@ char_width (int c, struct Lisp_Char_Table *dp) | |||
| 302 | if (CHARACTERP (ch)) | 292 | if (CHARACTERP (ch)) |
| 303 | { | 293 | { |
| 304 | int w = CHAR_WIDTH (XFASTINT (ch)); | 294 | int w = CHAR_WIDTH (XFASTINT (ch)); |
| 305 | if (INT_ADD_OVERFLOW (width, w)) | 295 | if (INT_ADD_WRAPV (width, w, &width)) |
| 306 | string_overflow (); | 296 | string_overflow (); |
| 307 | width += w; | ||
| 308 | } | 297 | } |
| 309 | } | 298 | } |
| 310 | } | 299 | } |
| @@ -349,20 +338,16 @@ c_string_width (const unsigned char *str, ptrdiff_t len, int precision, | |||
| 349 | int c = STRING_CHAR_AND_LENGTH (str + i_byte, bytes); | 338 | int c = STRING_CHAR_AND_LENGTH (str + i_byte, bytes); |
| 350 | ptrdiff_t thiswidth = char_width (c, dp); | 339 | ptrdiff_t thiswidth = char_width (c, dp); |
| 351 | 340 | ||
| 352 | if (precision <= 0) | 341 | if (0 < precision && precision - width < thiswidth) |
| 353 | { | ||
| 354 | if (INT_ADD_OVERFLOW (width, thiswidth)) | ||
| 355 | string_overflow (); | ||
| 356 | } | ||
| 357 | else if (precision - width < thiswidth) | ||
| 358 | { | 342 | { |
| 359 | *nchars = i; | 343 | *nchars = i; |
| 360 | *nbytes = i_byte; | 344 | *nbytes = i_byte; |
| 361 | return width; | 345 | return width; |
| 362 | } | 346 | } |
| 347 | if (INT_ADD_WRAPV (thiswidth, width, &width)) | ||
| 348 | string_overflow (); | ||
| 363 | i++; | 349 | i++; |
| 364 | i_byte += bytes; | 350 | i_byte += bytes; |
| 365 | width += thiswidth; | ||
| 366 | } | 351 | } |
| 367 | 352 | ||
| 368 | if (precision > 0) | 353 | if (precision > 0) |
| @@ -436,22 +421,16 @@ lisp_string_width (Lisp_Object string, ptrdiff_t precision, | |||
| 436 | thiswidth = char_width (c, dp); | 421 | thiswidth = char_width (c, dp); |
| 437 | } | 422 | } |
| 438 | 423 | ||
| 439 | if (precision <= 0) | 424 | if (0 < precision && precision - width < thiswidth) |
| 440 | { | ||
| 441 | #ifdef emacs | ||
| 442 | if (INT_ADD_OVERFLOW (width, thiswidth)) | ||
| 443 | string_overflow (); | ||
| 444 | #endif | ||
| 445 | } | ||
| 446 | else if (precision - width < thiswidth) | ||
| 447 | { | 425 | { |
| 448 | *nchars = i; | 426 | *nchars = i; |
| 449 | *nbytes = i_byte; | 427 | *nbytes = i_byte; |
| 450 | return width; | 428 | return width; |
| 451 | } | 429 | } |
| 430 | if (INT_ADD_WRAPV (thiswidth, width, &width)) | ||
| 431 | string_overflow (); | ||
| 452 | i += chars; | 432 | i += chars; |
| 453 | i_byte += bytes; | 433 | i_byte += bytes; |
| 454 | width += thiswidth; | ||
| 455 | } | 434 | } |
| 456 | 435 | ||
| 457 | if (precision > 0) | 436 | if (precision > 0) |
| @@ -657,9 +636,8 @@ count_size_as_multibyte (const unsigned char *str, ptrdiff_t len) | |||
| 657 | for (bytes = 0; str < endp; str++) | 636 | for (bytes = 0; str < endp; str++) |
| 658 | { | 637 | { |
| 659 | int n = *str < 0x80 ? 1 : 2; | 638 | int n = *str < 0x80 ? 1 : 2; |
| 660 | if (INT_ADD_OVERFLOW (bytes, n)) | 639 | if (INT_ADD_WRAPV (bytes, n, &bytes)) |
| 661 | string_overflow (); | 640 | string_overflow (); |
| 662 | bytes += n; | ||
| 663 | } | 641 | } |
| 664 | return bytes; | 642 | return bytes; |
| 665 | } | 643 | } |
| @@ -795,6 +773,7 @@ string_escape_byte8 (Lisp_Object string) | |||
| 795 | ptrdiff_t nbytes = SBYTES (string); | 773 | ptrdiff_t nbytes = SBYTES (string); |
| 796 | bool multibyte = STRING_MULTIBYTE (string); | 774 | bool multibyte = STRING_MULTIBYTE (string); |
| 797 | ptrdiff_t byte8_count; | 775 | ptrdiff_t byte8_count; |
| 776 | ptrdiff_t thrice_byte8_count, uninit_nchars, uninit_nbytes; | ||
| 798 | const unsigned char *src, *src_end; | 777 | const unsigned char *src, *src_end; |
| 799 | unsigned char *dst; | 778 | unsigned char *dst; |
| 800 | Lisp_Object val; | 779 | Lisp_Object val; |
| @@ -808,23 +787,23 @@ string_escape_byte8 (Lisp_Object string) | |||
| 808 | if (byte8_count == 0) | 787 | if (byte8_count == 0) |
| 809 | return string; | 788 | return string; |
| 810 | 789 | ||
| 790 | if (INT_MULTIPLY_WRAPV (byte8_count, 3, &thrice_byte8_count)) | ||
| 791 | string_overflow (); | ||
| 792 | |||
| 811 | if (multibyte) | 793 | if (multibyte) |
| 812 | { | 794 | { |
| 813 | if ((MOST_POSITIVE_FIXNUM - nchars) / 3 < byte8_count | ||
| 814 | || (STRING_BYTES_BOUND - nbytes) / 2 < byte8_count) | ||
| 815 | string_overflow (); | ||
| 816 | |||
| 817 | /* Convert 2-byte sequence of byte8 chars to 4-byte octal. */ | 795 | /* Convert 2-byte sequence of byte8 chars to 4-byte octal. */ |
| 818 | val = make_uninit_multibyte_string (nchars + byte8_count * 3, | 796 | if (INT_ADD_WRAPV (nchars, thrice_byte8_count, &uninit_nchars) |
| 819 | nbytes + byte8_count * 2); | 797 | || INT_ADD_WRAPV (nbytes, 2 * byte8_count, &uninit_nbytes)) |
| 798 | string_overflow (); | ||
| 799 | val = make_uninit_multibyte_string (uninit_nchars, uninit_nbytes); | ||
| 820 | } | 800 | } |
| 821 | else | 801 | else |
| 822 | { | 802 | { |
| 823 | if ((STRING_BYTES_BOUND - nbytes) / 3 < byte8_count) | ||
| 824 | string_overflow (); | ||
| 825 | |||
| 826 | /* Convert 1-byte sequence of byte8 chars to 4-byte octal. */ | 803 | /* Convert 1-byte sequence of byte8 chars to 4-byte octal. */ |
| 827 | val = make_uninit_string (nbytes + byte8_count * 3); | 804 | if (INT_ADD_WRAPV (thrice_byte8_count, nbytes, &uninit_nbytes)) |
| 805 | string_overflow (); | ||
| 806 | val = make_uninit_string (uninit_nbytes); | ||
| 828 | } | 807 | } |
| 829 | 808 | ||
| 830 | src = SDATA (string); | 809 | src = SDATA (string); |
| @@ -981,8 +960,6 @@ character is not ASCII nor 8-bit character, an error is signaled. */) | |||
| 981 | return make_number (c); | 960 | return make_number (c); |
| 982 | } | 961 | } |
| 983 | 962 | ||
| 984 | #ifdef emacs | ||
| 985 | |||
| 986 | /* Return true if C is an alphabetic character. */ | 963 | /* Return true if C is an alphabetic character. */ |
| 987 | bool | 964 | bool |
| 988 | alphabeticp (int c) | 965 | alphabeticp (int c) |
| @@ -1131,5 +1108,3 @@ See The Unicode Standard for the meaning of those values. */); | |||
| 1131 | /* The correct char-table is setup in characters.el. */ | 1108 | /* The correct char-table is setup in characters.el. */ |
| 1132 | Vunicode_category_table = Qnil; | 1109 | Vunicode_category_table = Qnil; |
| 1133 | } | 1110 | } |
| 1134 | |||
| 1135 | #endif /* emacs */ | ||
diff --git a/src/coding.c b/src/coding.c index 0b42a36543c..85b97ce6174 100644 --- a/src/coding.c +++ b/src/coding.c | |||
| @@ -1008,11 +1008,12 @@ coding_change_destination (struct coding_system *coding) | |||
| 1008 | static void | 1008 | static void |
| 1009 | coding_alloc_by_realloc (struct coding_system *coding, ptrdiff_t bytes) | 1009 | coding_alloc_by_realloc (struct coding_system *coding, ptrdiff_t bytes) |
| 1010 | { | 1010 | { |
| 1011 | if (STRING_BYTES_BOUND - coding->dst_bytes < bytes) | 1011 | ptrdiff_t newbytes; |
| 1012 | if (INT_ADD_WRAPV (coding->dst_bytes, bytes, &newbytes) | ||
| 1013 | || SIZE_MAX < newbytes) | ||
| 1012 | string_overflow (); | 1014 | string_overflow (); |
| 1013 | coding->destination = xrealloc (coding->destination, | 1015 | coding->destination = xrealloc (coding->destination, newbytes); |
| 1014 | coding->dst_bytes + bytes); | 1016 | coding->dst_bytes = newbytes; |
| 1015 | coding->dst_bytes += bytes; | ||
| 1016 | } | 1017 | } |
| 1017 | 1018 | ||
| 1018 | static void | 1019 | static void |
| @@ -7048,14 +7049,12 @@ produce_chars (struct coding_system *coding, Lisp_Object translation_table, | |||
| 7048 | if ((dst_end - dst) / MAX_MULTIBYTE_LENGTH < to_nchars) | 7049 | if ((dst_end - dst) / MAX_MULTIBYTE_LENGTH < to_nchars) |
| 7049 | { | 7050 | { |
| 7050 | eassert (growable_destination (coding)); | 7051 | eassert (growable_destination (coding)); |
| 7051 | if (((min (PTRDIFF_MAX, SIZE_MAX) - (buf_end - buf)) | 7052 | ptrdiff_t dst_size; |
| 7052 | / MAX_MULTIBYTE_LENGTH) | 7053 | if (INT_MULTIPLY_WRAPV (to_nchars, MAX_MULTIBYTE_LENGTH, |
| 7053 | < to_nchars) | 7054 | &dst_size) |
| 7055 | || INT_ADD_WRAPV (buf_end - buf, dst_size, &dst_size)) | ||
| 7054 | memory_full (SIZE_MAX); | 7056 | memory_full (SIZE_MAX); |
| 7055 | dst = alloc_destination (coding, | 7057 | dst = alloc_destination (coding, dst_size, dst); |
| 7056 | buf_end - buf | ||
| 7057 | + MAX_MULTIBYTE_LENGTH * to_nchars, | ||
| 7058 | dst); | ||
| 7059 | if (EQ (coding->src_object, coding->dst_object)) | 7058 | if (EQ (coding->src_object, coding->dst_object)) |
| 7060 | { | 7059 | { |
| 7061 | coding_set_source (coding); | 7060 | coding_set_source (coding); |
diff --git a/src/data.c b/src/data.c index 4db93f5625f..ccec15f430a 100644 --- a/src/data.c +++ b/src/data.c | |||
| @@ -2631,30 +2631,16 @@ arith_driver (enum arithop code, ptrdiff_t nargs, Lisp_Object *args) | |||
| 2631 | switch (code) | 2631 | switch (code) |
| 2632 | { | 2632 | { |
| 2633 | case Aadd: | 2633 | case Aadd: |
| 2634 | if (INT_ADD_OVERFLOW (accum, next)) | 2634 | overflow |= INT_ADD_WRAPV (accum, next, &accum); |
| 2635 | { | ||
| 2636 | overflow = 1; | ||
| 2637 | accum &= INTMASK; | ||
| 2638 | } | ||
| 2639 | accum += next; | ||
| 2640 | break; | 2635 | break; |
| 2641 | case Asub: | 2636 | case Asub: |
| 2642 | if (INT_SUBTRACT_OVERFLOW (accum, next)) | 2637 | if (! argnum) |
| 2643 | { | 2638 | accum = nargs == 1 ? - next : next; |
| 2644 | overflow = 1; | 2639 | else |
| 2645 | accum &= INTMASK; | 2640 | overflow |= INT_SUBTRACT_WRAPV (accum, next, &accum); |
| 2646 | } | ||
| 2647 | accum = argnum ? accum - next : nargs == 1 ? - next : next; | ||
| 2648 | break; | 2641 | break; |
| 2649 | case Amult: | 2642 | case Amult: |
| 2650 | if (INT_MULTIPLY_OVERFLOW (accum, next)) | 2643 | overflow |= INT_MULTIPLY_WRAPV (accum, next, &accum); |
| 2651 | { | ||
| 2652 | EMACS_UINT a = accum, b = next, ab = a * b; | ||
| 2653 | overflow = 1; | ||
| 2654 | accum = ab & INTMASK; | ||
| 2655 | } | ||
| 2656 | else | ||
| 2657 | accum *= next; | ||
| 2658 | break; | 2644 | break; |
| 2659 | case Adiv: | 2645 | case Adiv: |
| 2660 | if (! (argnum || nargs == 1)) | 2646 | if (! (argnum || nargs == 1)) |
| @@ -2663,7 +2649,10 @@ arith_driver (enum arithop code, ptrdiff_t nargs, Lisp_Object *args) | |||
| 2663 | { | 2649 | { |
| 2664 | if (next == 0) | 2650 | if (next == 0) |
| 2665 | xsignal0 (Qarith_error); | 2651 | xsignal0 (Qarith_error); |
| 2666 | accum /= next; | 2652 | if (INT_DIVIDE_OVERFLOW (accum, next)) |
| 2653 | overflow = true; | ||
| 2654 | else | ||
| 2655 | accum /= next; | ||
| 2667 | } | 2656 | } |
| 2668 | break; | 2657 | break; |
| 2669 | case Alogand: | 2658 | case Alogand: |
diff --git a/src/dispnew.c b/src/dispnew.c index 1a822f06365..64c84aec6f9 100644 --- a/src/dispnew.c +++ b/src/dispnew.c | |||
| @@ -1331,10 +1331,8 @@ realloc_glyph_pool (struct glyph_pool *pool, struct dim matrix_dim) | |||
| 1331 | || matrix_dim.width != pool->ncolumns); | 1331 | || matrix_dim.width != pool->ncolumns); |
| 1332 | 1332 | ||
| 1333 | /* Enlarge the glyph pool. */ | 1333 | /* Enlarge the glyph pool. */ |
| 1334 | needed = matrix_dim.width; | 1334 | if (INT_MULTIPLY_WRAPV (matrix_dim.height, matrix_dim.width, &needed)) |
| 1335 | if (INT_MULTIPLY_OVERFLOW (needed, matrix_dim.height)) | ||
| 1336 | memory_full (SIZE_MAX); | 1335 | memory_full (SIZE_MAX); |
| 1337 | needed *= matrix_dim.height; | ||
| 1338 | if (needed > pool->nglyphs) | 1336 | if (needed > pool->nglyphs) |
| 1339 | { | 1337 | { |
| 1340 | ptrdiff_t old_nglyphs = pool->nglyphs; | 1338 | ptrdiff_t old_nglyphs = pool->nglyphs; |
| @@ -6094,15 +6092,15 @@ init_display (void) | |||
| 6094 | struct frame *sf = SELECTED_FRAME (); | 6092 | struct frame *sf = SELECTED_FRAME (); |
| 6095 | int width = FRAME_TOTAL_COLS (sf); | 6093 | int width = FRAME_TOTAL_COLS (sf); |
| 6096 | int height = FRAME_TOTAL_LINES (sf); | 6094 | int height = FRAME_TOTAL_LINES (sf); |
| 6095 | int area; | ||
| 6097 | 6096 | ||
| 6098 | /* If these sizes are so big they cause overflow, just ignore the | 6097 | /* If these sizes are so big they cause overflow, just ignore the |
| 6099 | change. It's not clear what better we could do. The rest of | 6098 | change. It's not clear what better we could do. The rest of |
| 6100 | the code assumes that (width + 2) * height * sizeof (struct glyph) | 6099 | the code assumes that (width + 2) * height * sizeof (struct glyph) |
| 6101 | does not overflow and does not exceed PTRDIFF_MAX or SIZE_MAX. */ | 6100 | does not overflow and does not exceed PTRDIFF_MAX or SIZE_MAX. */ |
| 6102 | if (INT_ADD_OVERFLOW (width, 2) | 6101 | if (INT_ADD_WRAPV (width, 2, &area) |
| 6103 | || INT_MULTIPLY_OVERFLOW (width + 2, height) | 6102 | || INT_MULTIPLY_WRAPV (height, area, &area) |
| 6104 | || (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (struct glyph) | 6103 | || min (PTRDIFF_MAX, SIZE_MAX) / sizeof (struct glyph) < area) |
| 6105 | < (width + 2) * height)) | ||
| 6106 | fatal ("screen size %dx%d too big", width, height); | 6104 | fatal ("screen size %dx%d too big", width, height); |
| 6107 | } | 6105 | } |
| 6108 | 6106 | ||
diff --git a/src/editfns.c b/src/editfns.c index 050eb2ac6ec..316d9408065 100644 --- a/src/editfns.c +++ b/src/editfns.c | |||
| @@ -3887,9 +3887,12 @@ styled_format (ptrdiff_t nargs, Lisp_Object *args, bool message) | |||
| 3887 | ptrdiff_t formatlen = SBYTES (args[0]); | 3887 | ptrdiff_t formatlen = SBYTES (args[0]); |
| 3888 | 3888 | ||
| 3889 | /* Allocate the info and discarded tables. */ | 3889 | /* Allocate the info and discarded tables. */ |
| 3890 | if ((SIZE_MAX - formatlen) / sizeof (struct info) <= nargs) | 3890 | ptrdiff_t alloca_size; |
| 3891 | if (INT_MULTIPLY_WRAPV (nargs, sizeof *info, &alloca_size) | ||
| 3892 | || INT_ADD_WRAPV (sizeof *info, alloca_size, &alloca_size) | ||
| 3893 | || INT_ADD_WRAPV (formatlen, alloca_size, &alloca_size) | ||
| 3894 | || SIZE_MAX < alloca_size) | ||
| 3891 | memory_full (SIZE_MAX); | 3895 | memory_full (SIZE_MAX); |
| 3892 | size_t alloca_size = (nargs + 1) * sizeof *info + formatlen; | ||
| 3893 | /* info[0] is unused. Unused elements have -1 for start. */ | 3896 | /* info[0] is unused. Unused elements have -1 for start. */ |
| 3894 | info = SAFE_ALLOCA (alloca_size); | 3897 | info = SAFE_ALLOCA (alloca_size); |
| 3895 | memset (info, 0, alloca_size); | 3898 | memset (info, 0, alloca_size); |
| @@ -2389,9 +2389,9 @@ ARRAY is a vector, string, char-table, or bool-vector. */) | |||
| 2389 | unsigned char str[MAX_MULTIBYTE_LENGTH]; | 2389 | unsigned char str[MAX_MULTIBYTE_LENGTH]; |
| 2390 | int len = CHAR_STRING (charval, str); | 2390 | int len = CHAR_STRING (charval, str); |
| 2391 | ptrdiff_t size_byte = SBYTES (array); | 2391 | ptrdiff_t size_byte = SBYTES (array); |
| 2392 | ptrdiff_t product; | ||
| 2392 | 2393 | ||
| 2393 | if (INT_MULTIPLY_OVERFLOW (SCHARS (array), len) | 2394 | if (INT_MULTIPLY_WRAPV (size, len, &product) || product != size_byte) |
| 2394 | || SCHARS (array) * len != size_byte) | ||
| 2395 | error ("Attempt to change byte length of a string"); | 2395 | error ("Attempt to change byte length of a string"); |
| 2396 | for (idx = 0; idx < size_byte; idx++) | 2396 | for (idx = 0; idx < size_byte; idx++) |
| 2397 | *p++ = str[idx % len]; | 2397 | *p++ = str[idx % len]; |
diff --git a/src/ftfont.c b/src/ftfont.c index fb1addb7a0c..57ded171de4 100644 --- a/src/ftfont.c +++ b/src/ftfont.c | |||
| @@ -2561,20 +2561,21 @@ ftfont_shape_by_flt (Lisp_Object lgstring, struct font *font, | |||
| 2561 | } | 2561 | } |
| 2562 | } | 2562 | } |
| 2563 | 2563 | ||
| 2564 | if (INT_MAX / 2 < len) | 2564 | int len2; |
| 2565 | if (INT_MULTIPLY_WRAPV (len, 2, &len2)) | ||
| 2565 | memory_full (SIZE_MAX); | 2566 | memory_full (SIZE_MAX); |
| 2566 | 2567 | ||
| 2567 | if (gstring.allocated == 0) | 2568 | if (gstring.allocated == 0) |
| 2568 | { | 2569 | { |
| 2569 | gstring.glyph_size = sizeof (MFLTGlyphFT); | 2570 | gstring.glyph_size = sizeof (MFLTGlyphFT); |
| 2570 | gstring.glyphs = xnmalloc (len * 2, sizeof (MFLTGlyphFT)); | 2571 | gstring.glyphs = xnmalloc (len2, sizeof (MFLTGlyphFT)); |
| 2571 | gstring.allocated = len * 2; | 2572 | gstring.allocated = len2; |
| 2572 | } | 2573 | } |
| 2573 | else if (gstring.allocated < len * 2) | 2574 | else if (gstring.allocated < len2) |
| 2574 | { | 2575 | { |
| 2575 | gstring.glyphs = xnrealloc (gstring.glyphs, len * 2, | 2576 | gstring.glyphs = xnrealloc (gstring.glyphs, len2, |
| 2576 | sizeof (MFLTGlyphFT)); | 2577 | sizeof (MFLTGlyphFT)); |
| 2577 | gstring.allocated = len * 2; | 2578 | gstring.allocated = len2; |
| 2578 | } | 2579 | } |
| 2579 | glyphs = (MFLTGlyphFT *) (gstring.glyphs); | 2580 | glyphs = (MFLTGlyphFT *) (gstring.glyphs); |
| 2580 | memset (glyphs, 0, len * sizeof (MFLTGlyphFT)); | 2581 | memset (glyphs, 0, len * sizeof (MFLTGlyphFT)); |
| @@ -2624,11 +2625,12 @@ ftfont_shape_by_flt (Lisp_Object lgstring, struct font *font, | |||
| 2624 | int result = mflt_run (&gstring, 0, len, &flt_font_ft.flt_font, flt); | 2625 | int result = mflt_run (&gstring, 0, len, &flt_font_ft.flt_font, flt); |
| 2625 | if (result != -2) | 2626 | if (result != -2) |
| 2626 | break; | 2627 | break; |
| 2627 | if (INT_MAX / 2 < gstring.allocated) | 2628 | int len2; |
| 2629 | if (INT_MULTIPLY_WRAPV (gstring.allocated, 2, &len2)) | ||
| 2628 | memory_full (SIZE_MAX); | 2630 | memory_full (SIZE_MAX); |
| 2629 | gstring.glyphs = xnrealloc (gstring.glyphs, | 2631 | gstring.glyphs = xnrealloc (gstring.glyphs, |
| 2630 | gstring.allocated, 2 * sizeof (MFLTGlyphFT)); | 2632 | gstring.allocated, 2 * sizeof (MFLTGlyphFT)); |
| 2631 | gstring.allocated *= 2; | 2633 | gstring.allocated = len2; |
| 2632 | } | 2634 | } |
| 2633 | if (gstring.used > LGSTRING_GLYPH_LEN (lgstring)) | 2635 | if (gstring.used > LGSTRING_GLYPH_LEN (lgstring)) |
| 2634 | return Qnil; | 2636 | return Qnil; |
diff --git a/src/gnutls.c b/src/gnutls.c index 864cac5f511..0c69b0001ee 100644 --- a/src/gnutls.c +++ b/src/gnutls.c | |||
| @@ -781,10 +781,11 @@ static Lisp_Object | |||
| 781 | gnutls_hex_string (unsigned char *buf, ptrdiff_t buf_size, const char *prefix) | 781 | gnutls_hex_string (unsigned char *buf, ptrdiff_t buf_size, const char *prefix) |
| 782 | { | 782 | { |
| 783 | ptrdiff_t prefix_length = strlen (prefix); | 783 | ptrdiff_t prefix_length = strlen (prefix); |
| 784 | if ((STRING_BYTES_BOUND - prefix_length) / 3 < buf_size) | 784 | ptrdiff_t retlen; |
| 785 | if (INT_MULTIPLY_WRAPV (buf_size, 3, &retlen) | ||
| 786 | || INT_ADD_WRAPV (prefix_length - (buf_size != 0), retlen, &retlen)) | ||
| 785 | string_overflow (); | 787 | string_overflow (); |
| 786 | Lisp_Object ret = make_uninit_string (prefix_length + 3 * buf_size | 788 | Lisp_Object ret = make_uninit_string (retlen); |
| 787 | - (buf_size != 0)); | ||
| 788 | char *string = SSDATA (ret); | 789 | char *string = SSDATA (ret); |
| 789 | strcpy (string, prefix); | 790 | strcpy (string, prefix); |
| 790 | 791 | ||
diff --git a/src/gtkutil.c b/src/gtkutil.c index 701bcab7060..90683eba7b8 100644 --- a/src/gtkutil.c +++ b/src/gtkutil.c | |||
| @@ -517,9 +517,12 @@ get_utf8_string (const char *str) | |||
| 517 | if (cp) g_free (cp); | 517 | if (cp) g_free (cp); |
| 518 | 518 | ||
| 519 | len = strlen (str); | 519 | len = strlen (str); |
| 520 | if ((min (PTRDIFF_MAX, SIZE_MAX) - len - 1) / 4 < nr_bad) | 520 | ptrdiff_t alloc; |
| 521 | if (INT_MULTIPLY_WRAPV (nr_bad, 4, &alloc) | ||
| 522 | || INT_ADD_WRAPV (len + 1, alloc, &alloc) | ||
| 523 | || SIZE_MAX < alloc) | ||
| 521 | memory_full (SIZE_MAX); | 524 | memory_full (SIZE_MAX); |
| 522 | up = utf8_str = xmalloc (len + nr_bad * 4 + 1); | 525 | up = utf8_str = xmalloc (alloc); |
| 523 | p = (unsigned char *)str; | 526 | p = (unsigned char *)str; |
| 524 | 527 | ||
| 525 | while (! (cp = g_locale_to_utf8 ((char *)p, -1, &bytes_read, | 528 | while (! (cp = g_locale_to_utf8 ((char *)p, -1, &bytes_read, |
diff --git a/src/image.c b/src/image.c index 928eb5cfa37..41687eb885c 100644 --- a/src/image.c +++ b/src/image.c | |||
| @@ -4662,13 +4662,16 @@ x_to_xcolors (struct frame *f, struct image *img, bool rgb_p) | |||
| 4662 | int x, y; | 4662 | int x, y; |
| 4663 | XColor *colors, *p; | 4663 | XColor *colors, *p; |
| 4664 | XImagePtr_or_DC ximg; | 4664 | XImagePtr_or_DC ximg; |
| 4665 | ptrdiff_t nbytes; | ||
| 4665 | #ifdef HAVE_NTGUI | 4666 | #ifdef HAVE_NTGUI |
| 4666 | HGDIOBJ prev; | 4667 | HGDIOBJ prev; |
| 4667 | #endif /* HAVE_NTGUI */ | 4668 | #endif /* HAVE_NTGUI */ |
| 4668 | 4669 | ||
| 4669 | if (img->height > min (PTRDIFF_MAX, SIZE_MAX) / sizeof *colors / img->width) | 4670 | if (INT_MULTIPLY_WRAPV (sizeof *colors, img->width, &nbytes) |
| 4671 | || INT_MULTIPLY_WRAPV (img->height, nbytes, &nbytes) | ||
| 4672 | || SIZE_MAX < nbytes) | ||
| 4670 | memory_full (SIZE_MAX); | 4673 | memory_full (SIZE_MAX); |
| 4671 | colors = xmalloc (sizeof *colors * img->width * img->height); | 4674 | colors = xmalloc (nbytes); |
| 4672 | 4675 | ||
| 4673 | /* Get the X image or create a memory device context for IMG. */ | 4676 | /* Get the X image or create a memory device context for IMG. */ |
| 4674 | ximg = image_get_x_image_or_dc (f, img, 0, &prev); | 4677 | ximg = image_get_x_image_or_dc (f, img, 0, &prev); |
| @@ -4801,15 +4804,17 @@ x_detect_edges (struct frame *f, struct image *img, int *matrix, int color_adjus | |||
| 4801 | XColor *colors = x_to_xcolors (f, img, 1); | 4804 | XColor *colors = x_to_xcolors (f, img, 1); |
| 4802 | XColor *new, *p; | 4805 | XColor *new, *p; |
| 4803 | int x, y, i, sum; | 4806 | int x, y, i, sum; |
| 4807 | ptrdiff_t nbytes; | ||
| 4804 | 4808 | ||
| 4805 | for (i = sum = 0; i < 9; ++i) | 4809 | for (i = sum = 0; i < 9; ++i) |
| 4806 | sum += eabs (matrix[i]); | 4810 | sum += eabs (matrix[i]); |
| 4807 | 4811 | ||
| 4808 | #define COLOR(A, X, Y) ((A) + (Y) * img->width + (X)) | 4812 | #define COLOR(A, X, Y) ((A) + (Y) * img->width + (X)) |
| 4809 | 4813 | ||
| 4810 | if (img->height > min (PTRDIFF_MAX, SIZE_MAX) / sizeof *new / img->width) | 4814 | if (INT_MULTIPLY_WRAPV (sizeof *new, img->width, &nbytes) |
| 4815 | || INT_MULTIPLY_WRAPV (img->height, nbytes, &nbytes)) | ||
| 4811 | memory_full (SIZE_MAX); | 4816 | memory_full (SIZE_MAX); |
| 4812 | new = xmalloc (sizeof *new * img->width * img->height); | 4817 | new = xmalloc (nbytes); |
| 4813 | 4818 | ||
| 4814 | for (y = 0; y < img->height; ++y) | 4819 | for (y = 0; y < img->height; ++y) |
| 4815 | { | 4820 | { |
| @@ -5898,6 +5903,7 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c) | |||
| 5898 | png_uint_32 row_bytes; | 5903 | png_uint_32 row_bytes; |
| 5899 | bool transparent_p; | 5904 | bool transparent_p; |
| 5900 | struct png_memory_storage tbr; /* Data to be read */ | 5905 | struct png_memory_storage tbr; /* Data to be read */ |
| 5906 | ptrdiff_t nbytes; | ||
| 5901 | 5907 | ||
| 5902 | #ifdef USE_CAIRO | 5908 | #ifdef USE_CAIRO |
| 5903 | unsigned char *data = 0; | 5909 | unsigned char *data = 0; |
| @@ -6102,10 +6108,10 @@ png_load_body (struct frame *f, struct image *img, struct png_load_context *c) | |||
| 6102 | row_bytes = png_get_rowbytes (png_ptr, info_ptr); | 6108 | row_bytes = png_get_rowbytes (png_ptr, info_ptr); |
| 6103 | 6109 | ||
| 6104 | /* Allocate memory for the image. */ | 6110 | /* Allocate memory for the image. */ |
| 6105 | if (height > min (PTRDIFF_MAX, SIZE_MAX) / sizeof *rows | 6111 | if (INT_MULTIPLY_WRAPV (row_bytes, sizeof *pixels, &nbytes) |
| 6106 | || row_bytes > min (PTRDIFF_MAX, SIZE_MAX) / sizeof *pixels / height) | 6112 | || INT_MULTIPLY_WRAPV (nbytes, height, &nbytes)) |
| 6107 | memory_full (SIZE_MAX); | 6113 | memory_full (SIZE_MAX); |
| 6108 | c->pixels = pixels = xmalloc (sizeof *pixels * row_bytes * height); | 6114 | c->pixels = pixels = xmalloc (nbytes); |
| 6109 | c->rows = rows = xmalloc (height * sizeof *rows); | 6115 | c->rows = rows = xmalloc (height * sizeof *rows); |
| 6110 | for (i = 0; i < height; ++i) | 6116 | for (i = 0; i < height; ++i) |
| 6111 | rows[i] = pixels + i * row_bytes; | 6117 | rows[i] = pixels + i * row_bytes; |
diff --git a/src/keymap.c b/src/keymap.c index c988d12fe80..c28885ab132 100644 --- a/src/keymap.c +++ b/src/keymap.c | |||
| @@ -1984,9 +1984,10 @@ For an approximate inverse of this, see `kbd'. */) | |||
| 1984 | size += XINT (Flength (prefix)); | 1984 | size += XINT (Flength (prefix)); |
| 1985 | 1985 | ||
| 1986 | /* This has one extra element at the end that we don't pass to Fconcat. */ | 1986 | /* This has one extra element at the end that we don't pass to Fconcat. */ |
| 1987 | if (min (PTRDIFF_MAX, SIZE_MAX) / word_size / 4 < size) | 1987 | EMACS_INT size4; |
| 1988 | if (INT_MULTIPLY_WRAPV (size, 4, &size4)) | ||
| 1988 | memory_full (SIZE_MAX); | 1989 | memory_full (SIZE_MAX); |
| 1989 | SAFE_ALLOCA_LISP (args, size * 4); | 1990 | SAFE_ALLOCA_LISP (args, size4); |
| 1990 | 1991 | ||
| 1991 | /* In effect, this computes | 1992 | /* In effect, this computes |
| 1992 | (mapconcat 'single-key-description keys " ") | 1993 | (mapconcat 'single-key-description keys " ") |
diff --git a/src/lisp.h b/src/lisp.h index a1409d1af8c..784ab18c0ee 100644 --- a/src/lisp.h +++ b/src/lisp.h | |||
| @@ -4447,40 +4447,24 @@ extern void *record_xmalloc (size_t) ATTRIBUTE_ALLOC_SIZE ((1)); | |||
| 4447 | } \ | 4447 | } \ |
| 4448 | } while (false) | 4448 | } while (false) |
| 4449 | 4449 | ||
| 4450 | |||
| 4451 | /* Return floor (NBYTES / WORD_SIZE). */ | ||
| 4452 | |||
| 4453 | INLINE ptrdiff_t | ||
| 4454 | lisp_word_count (ptrdiff_t nbytes) | ||
| 4455 | { | ||
| 4456 | if (-1 >> 1 == -1) | ||
| 4457 | switch (word_size + 0) | ||
| 4458 | { | ||
| 4459 | case 2: return nbytes >> 1; | ||
| 4460 | case 4: return nbytes >> 2; | ||
| 4461 | case 8: return nbytes >> 3; | ||
| 4462 | case 16: return nbytes >> 4; | ||
| 4463 | default: break; | ||
| 4464 | } | ||
| 4465 | return nbytes / word_size - (nbytes % word_size < 0); | ||
| 4466 | } | ||
| 4467 | |||
| 4468 | /* SAFE_ALLOCA_LISP allocates an array of Lisp_Objects. */ | 4450 | /* SAFE_ALLOCA_LISP allocates an array of Lisp_Objects. */ |
| 4469 | 4451 | ||
| 4470 | #define SAFE_ALLOCA_LISP(buf, nelt) \ | 4452 | #define SAFE_ALLOCA_LISP(buf, nelt) \ |
| 4471 | do { \ | 4453 | do { \ |
| 4472 | if ((nelt) <= lisp_word_count (sa_avail)) \ | 4454 | ptrdiff_t alloca_nbytes; \ |
| 4473 | (buf) = AVAIL_ALLOCA ((nelt) * word_size); \ | 4455 | if (INT_MULTIPLY_WRAPV (nelt, word_size, &alloca_nbytes) \ |
| 4474 | else if ((nelt) <= min (PTRDIFF_MAX, SIZE_MAX) / word_size) \ | 4456 | || SIZE_MAX < alloca_nbytes) \ |
| 4457 | memory_full (SIZE_MAX); \ | ||
| 4458 | else if (alloca_nbytes <= sa_avail) \ | ||
| 4459 | (buf) = AVAIL_ALLOCA (alloca_nbytes); \ | ||
| 4460 | else \ | ||
| 4475 | { \ | 4461 | { \ |
| 4476 | Lisp_Object arg_; \ | 4462 | Lisp_Object arg_; \ |
| 4477 | (buf) = xmalloc ((nelt) * word_size); \ | 4463 | (buf) = xmalloc (alloca_nbytes); \ |
| 4478 | arg_ = make_save_memory (buf, nelt); \ | 4464 | arg_ = make_save_memory (buf, nelt); \ |
| 4479 | sa_must_free = true; \ | 4465 | sa_must_free = true; \ |
| 4480 | record_unwind_protect (free_save_value, arg_); \ | 4466 | record_unwind_protect (free_save_value, arg_); \ |
| 4481 | } \ | 4467 | } \ |
| 4482 | else \ | ||
| 4483 | memory_full (SIZE_MAX); \ | ||
| 4484 | } while (false) | 4468 | } while (false) |
| 4485 | 4469 | ||
| 4486 | 4470 | ||
diff --git a/src/term.c b/src/term.c index 245712ecfc4..6ab611d51e2 100644 --- a/src/term.c +++ b/src/term.c | |||
| @@ -532,10 +532,8 @@ encode_terminal_code (struct glyph *src, int src_len, | |||
| 532 | multibyte-form. But, it may be enlarged on demand if | 532 | multibyte-form. But, it may be enlarged on demand if |
| 533 | Vglyph_table contains a string or a composite glyph is | 533 | Vglyph_table contains a string or a composite glyph is |
| 534 | encountered. */ | 534 | encountered. */ |
| 535 | if (min (PTRDIFF_MAX, SIZE_MAX) / MAX_MULTIBYTE_LENGTH < src_len) | 535 | if (INT_MULTIPLY_WRAPV (src_len, MAX_MULTIBYTE_LENGTH, &required)) |
| 536 | memory_full (SIZE_MAX); | 536 | memory_full (SIZE_MAX); |
| 537 | required = src_len; | ||
| 538 | required *= MAX_MULTIBYTE_LENGTH; | ||
| 539 | if (encode_terminal_src_size < required) | 537 | if (encode_terminal_src_size < required) |
| 540 | encode_terminal_src = xpalloc (encode_terminal_src, | 538 | encode_terminal_src = xpalloc (encode_terminal_src, |
| 541 | &encode_terminal_src_size, | 539 | &encode_terminal_src_size, |
diff --git a/src/tparam.c b/src/tparam.c index 02047db2095..3a64059e0eb 100644 --- a/src/tparam.c +++ b/src/tparam.c | |||
| @@ -167,9 +167,9 @@ tparam1 (const char *string, char *outstring, int len, | |||
| 167 | doup++, append_len_incr = strlen (up); | 167 | doup++, append_len_incr = strlen (up); |
| 168 | else | 168 | else |
| 169 | doleft++, append_len_incr = strlen (left); | 169 | doleft++, append_len_incr = strlen (left); |
| 170 | if (INT_ADD_OVERFLOW (append_len, append_len_incr)) | 170 | if (INT_ADD_WRAPV (append_len_incr, |
| 171 | append_len, &append_len)) | ||
| 171 | memory_full (SIZE_MAX); | 172 | memory_full (SIZE_MAX); |
| 172 | append_len += append_len_incr; | ||
| 173 | } | 173 | } |
| 174 | } | 174 | } |
| 175 | *op++ = tem ? tem : 0200; | 175 | *op++ = tem ? tem : 0200; |
diff --git a/src/xselect.c b/src/xselect.c index 9d178a50d7a..41bd2bc40de 100644 --- a/src/xselect.c +++ b/src/xselect.c | |||
| @@ -2330,10 +2330,11 @@ x_property_data_to_lisp (struct frame *f, const unsigned char *data, | |||
| 2330 | Atom type, int format, unsigned long size) | 2330 | Atom type, int format, unsigned long size) |
| 2331 | { | 2331 | { |
| 2332 | ptrdiff_t format_bytes = format >> 3; | 2332 | ptrdiff_t format_bytes = format >> 3; |
| 2333 | if (PTRDIFF_MAX / format_bytes < size) | 2333 | ptrdiff_t data_bytes; |
| 2334 | if (INT_MULTIPLY_WRAPV (size, format_bytes, &data_bytes)) | ||
| 2334 | memory_full (SIZE_MAX); | 2335 | memory_full (SIZE_MAX); |
| 2335 | return selection_data_to_lisp_data (FRAME_DISPLAY_INFO (f), data, | 2336 | return selection_data_to_lisp_data (FRAME_DISPLAY_INFO (f), data, |
| 2336 | size * format_bytes, type, format); | 2337 | data_bytes, type, format); |
| 2337 | } | 2338 | } |
| 2338 | 2339 | ||
| 2339 | DEFUN ("x-get-atom-name", Fx_get_atom_name, | 2340 | DEFUN ("x-get-atom-name", Fx_get_atom_name, |
diff --git a/src/xsmfns.c b/src/xsmfns.c index b84f2ac58d9..8c4a6d3462c 100644 --- a/src/xsmfns.c +++ b/src/xsmfns.c | |||
| @@ -223,9 +223,8 @@ smc_save_yourself_CB (SmcConn smcConn, | |||
| 223 | props[props_idx]->name = xstrdup (SmRestartCommand); | 223 | props[props_idx]->name = xstrdup (SmRestartCommand); |
| 224 | props[props_idx]->type = xstrdup (SmLISTofARRAY8); | 224 | props[props_idx]->type = xstrdup (SmLISTofARRAY8); |
| 225 | /* /path/to/emacs, --smid=xxx --no-splash --chdir=dir ... */ | 225 | /* /path/to/emacs, --smid=xxx --no-splash --chdir=dir ... */ |
| 226 | if (INT_MAX - 3 < initial_argc) | 226 | if (INT_ADD_WRAPV (initial_argc, 3, &i)) |
| 227 | memory_full (SIZE_MAX); | 227 | memory_full (SIZE_MAX); |
| 228 | i = 3 + initial_argc; | ||
| 229 | props[props_idx]->num_vals = i; | 228 | props[props_idx]->num_vals = i; |
| 230 | vp = xnmalloc (i, sizeof *vp); | 229 | vp = xnmalloc (i, sizeof *vp); |
| 231 | props[props_idx]->vals = vp; | 230 | props[props_idx]->vals = vp; |
diff --git a/src/xterm.c b/src/xterm.c index 5e9c16b8af4..5756378bd3a 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -11773,7 +11773,6 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) | |||
| 11773 | struct terminal *terminal; | 11773 | struct terminal *terminal; |
| 11774 | struct x_display_info *dpyinfo; | 11774 | struct x_display_info *dpyinfo; |
| 11775 | XrmDatabase xrdb; | 11775 | XrmDatabase xrdb; |
| 11776 | ptrdiff_t lim; | ||
| 11777 | 11776 | ||
| 11778 | block_input (); | 11777 | block_input (); |
| 11779 | 11778 | ||
| @@ -11974,13 +11973,13 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) | |||
| 11974 | XSetAfterFunction (x_current_display, x_trace_wire); | 11973 | XSetAfterFunction (x_current_display, x_trace_wire); |
| 11975 | #endif | 11974 | #endif |
| 11976 | 11975 | ||
| 11977 | lim = min (PTRDIFF_MAX, SIZE_MAX) - sizeof "@"; | ||
| 11978 | Lisp_Object system_name = Fsystem_name (); | 11976 | Lisp_Object system_name = Fsystem_name (); |
| 11979 | if (lim - SBYTES (Vinvocation_name) < SBYTES (system_name)) | 11977 | ptrdiff_t nbytes; |
| 11978 | if (INT_ADD_WRAPV (SBYTES (Vinvocation_name), SBYTES (system_name) + 2, | ||
| 11979 | &nbytes)) | ||
| 11980 | memory_full (SIZE_MAX); | 11980 | memory_full (SIZE_MAX); |
| 11981 | dpyinfo->x_id = ++x_display_id; | 11981 | dpyinfo->x_id = ++x_display_id; |
| 11982 | dpyinfo->x_id_name = xmalloc (SBYTES (Vinvocation_name) | 11982 | dpyinfo->x_id_name = xmalloc (nbytes); |
| 11983 | + SBYTES (system_name) + 2); | ||
| 11984 | char *nametail = lispstpcpy (dpyinfo->x_id_name, Vinvocation_name); | 11983 | char *nametail = lispstpcpy (dpyinfo->x_id_name, Vinvocation_name); |
| 11985 | *nametail++ = '@'; | 11984 | *nametail++ = '@'; |
| 11986 | lispstpcpy (nametail, system_name); | 11985 | lispstpcpy (nametail, system_name); |