aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2015-11-08 22:47:01 -0800
committerPaul Eggert2015-11-08 22:48:28 -0800
commit1087305574fd61256d66eb0c995f8bb74bd91afe (patch)
tree9f0052e41a56c785575727931ff4abb8e7dfa7e0 /src
parentbcca6a2a028d05af3cb5b31a5a2c997f3f1f1d31 (diff)
downloademacs-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.c55
-rw-r--r--src/buffer.c11
-rw-r--r--src/casefiddle.c8
-rw-r--r--src/ccl.c8
-rw-r--r--src/character.c63
-rw-r--r--src/coding.c21
-rw-r--r--src/data.c31
-rw-r--r--src/dispnew.c12
-rw-r--r--src/editfns.c7
-rw-r--r--src/fns.c4
-rw-r--r--src/ftfont.c18
-rw-r--r--src/gnutls.c7
-rw-r--r--src/gtkutil.c7
-rw-r--r--src/image.c20
-rw-r--r--src/keymap.c5
-rw-r--r--src/lisp.h32
-rw-r--r--src/term.c4
-rw-r--r--src/tparam.c4
-rw-r--r--src/xselect.c5
-rw-r--r--src/xsmfns.c3
-rw-r--r--src/xterm.c9
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 *
802xnmalloc (ptrdiff_t nitems, ptrdiff_t item_size) 802xnmalloc (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 *
815xnrealloc (void *pa, ptrdiff_t nitems, ptrdiff_t item_size) 816xnrealloc (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 *
848xpalloc (void *pa, ptrdiff_t *nitems, ptrdiff_t nitems_incr_min, 850xpalloc (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)
diff --git a/src/ccl.c b/src/ccl.c
index bf2aa1254d4..9792717378d 100644
--- a/src/ccl.c
+++ b/src/ccl.c
@@ -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. */
52Lisp_Object Vchar_unify_table; 42Lisp_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. */
987bool 964bool
988alphabeticp (int c) 965alphabeticp (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)
1008static void 1008static void
1009coding_alloc_by_realloc (struct coding_system *coding, ptrdiff_t bytes) 1009coding_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
1018static void 1019static 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);
diff --git a/src/fns.c b/src/fns.c
index f545066fb07..46956668777 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -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
781gnutls_hex_string (unsigned char *buf, ptrdiff_t buf_size, const char *prefix) 781gnutls_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
4453INLINE ptrdiff_t
4454lisp_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
2339DEFUN ("x-get-atom-name", Fx_get_atom_name, 2340DEFUN ("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);