aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEli Zaretskii2016-09-24 12:36:43 +0300
committerEli Zaretskii2016-09-24 12:36:43 +0300
commit4822b56598f91489e050fcbf305d99b5e57b6791 (patch)
tree2854d047017c083e098dce74a8e9786f37230afc
parent23efc43d01462ff0e952dd149d26e90cbe8792f0 (diff)
parentb3e1b382456b0f7d108c57d6f902bbddfdd97b2a (diff)
downloademacs-4822b56598f91489e050fcbf305d99b5e57b6791.tar.gz
emacs-4822b56598f91489e050fcbf305d99b5e57b6791.zip
Merge branch 'master' of git.savannah.gnu.org:/srv/git/emacs
-rw-r--r--src/charset.c2
-rw-r--r--src/doprnt.c25
-rw-r--r--src/editfns.c15
-rw-r--r--src/emacs-module.c13
-rw-r--r--src/font.c7
-rw-r--r--src/keyboard.c8
-rw-r--r--src/lread.c10
-rw-r--r--src/xdisp.c64
8 files changed, 58 insertions, 86 deletions
diff --git a/src/charset.c b/src/charset.c
index 0c831f13591..cdbfe119515 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -435,7 +435,7 @@ read_hex (FILE *fp, bool *eof, bool *overflow)
435 n = 0; 435 n = 0;
436 while (c_isxdigit (c = getc (fp))) 436 while (c_isxdigit (c = getc (fp)))
437 { 437 {
438 if (UINT_MAX >> 4 < n) 438 if (INT_LEFT_SHIFT_OVERFLOW (n, 4))
439 *overflow = 1; 439 *overflow = 1;
440 n = ((n << 4) 440 n = ((n << 4)
441 | (c - ('0' <= c && c <= '9' ? '0' 441 | (c - ('0' <= c && c <= '9' ? '0'
diff --git a/src/doprnt.c b/src/doprnt.c
index 9d8b783565f..de2b89e1225 100644
--- a/src/doprnt.c
+++ b/src/doprnt.c
@@ -133,8 +133,11 @@ doprnt (char *buffer, ptrdiff_t bufsize, const char *format,
133 const char *fmt = format; /* Pointer into format string. */ 133 const char *fmt = format; /* Pointer into format string. */
134 char *bufptr = buffer; /* Pointer into output buffer. */ 134 char *bufptr = buffer; /* Pointer into output buffer. */
135 135
136 /* Enough to handle floating point formats with large numbers. */
137 enum { SIZE_BOUND_EXTRA = DBL_MAX_10_EXP + 50 };
138
136 /* Use this for sprintf unless we need something really big. */ 139 /* Use this for sprintf unless we need something really big. */
137 char tembuf[DBL_MAX_10_EXP + 100]; 140 char tembuf[SIZE_BOUND_EXTRA + 50];
138 141
139 /* Size of sprintf_buffer. */ 142 /* Size of sprintf_buffer. */
140 ptrdiff_t size_allocated = sizeof (tembuf); 143 ptrdiff_t size_allocated = sizeof (tembuf);
@@ -196,21 +199,19 @@ doprnt (char *buffer, ptrdiff_t bufsize, const char *format,
196 This might be a field width or a precision; e.g. 199 This might be a field width or a precision; e.g.
197 %1.1000f and %1000.1f both might need 1000+ bytes. 200 %1.1000f and %1000.1f both might need 1000+ bytes.
198 Parse the width or precision, checking for overflow. */ 201 Parse the width or precision, checking for overflow. */
199 ptrdiff_t n = *fmt - '0'; 202 int n = *fmt - '0';
203 bool overflow = false;
200 while (fmt + 1 < format_end 204 while (fmt + 1 < format_end
201 && '0' <= fmt[1] && fmt[1] <= '9') 205 && '0' <= fmt[1] && fmt[1] <= '9')
202 { 206 {
203 /* Avoid ptrdiff_t, size_t, and int overflow, as 207 overflow |= INT_MULTIPLY_WRAPV (n, 10, &n);
204 many sprintfs mishandle widths greater than INT_MAX. 208 overflow |= INT_ADD_WRAPV (n, fmt[1] - '0', &n);
205 This test is simple but slightly conservative: e.g.,
206 (INT_MAX - INT_MAX % 10) is reported as an overflow
207 even when it's not. */
208 if (n >= min (INT_MAX, min (PTRDIFF_MAX, SIZE_MAX)) / 10)
209 error ("Format width or precision too large");
210 n = n * 10 + fmt[1] - '0';
211 *string++ = *++fmt; 209 *string++ = *++fmt;
212 } 210 }
213 211
212 if (overflow
213 || min (PTRDIFF_MAX, SIZE_MAX) - SIZE_BOUND_EXTRA < n)
214 error ("Format width or precision too large");
214 if (size_bound < n) 215 if (size_bound < n)
215 size_bound = n; 216 size_bound = n;
216 } 217 }
@@ -244,9 +245,7 @@ doprnt (char *buffer, ptrdiff_t bufsize, const char *format,
244 245
245 /* Make the size bound large enough to handle floating point formats 246 /* Make the size bound large enough to handle floating point formats
246 with large numbers. */ 247 with large numbers. */
247 if (size_bound > min (PTRDIFF_MAX, SIZE_MAX) - DBL_MAX_10_EXP - 50) 248 size_bound += SIZE_BOUND_EXTRA;
248 error ("Format width or precision too large");
249 size_bound += DBL_MAX_10_EXP + 50;
250 249
251 /* Make sure we have that much. */ 250 /* Make sure we have that much. */
252 if (size_bound > size_allocated) 251 if (size_bound > size_allocated)
diff --git a/src/editfns.c b/src/editfns.c
index 835e432ae3d..c5b177e41f2 100644
--- a/src/editfns.c
+++ b/src/editfns.c
@@ -1523,17 +1523,8 @@ static EMACS_INT
1523hi_time (time_t t) 1523hi_time (time_t t)
1524{ 1524{
1525 time_t hi = t >> LO_TIME_BITS; 1525 time_t hi = t >> LO_TIME_BITS;
1526 1526 if (FIXNUM_OVERFLOW_P (hi))
1527 /* Check for overflow, helping the compiler for common cases where
1528 no runtime check is needed, and taking care not to convert
1529 negative numbers to unsigned before comparing them. */
1530 if (! ((! TYPE_SIGNED (time_t)
1531 || MOST_NEGATIVE_FIXNUM <= TIME_T_MIN >> LO_TIME_BITS
1532 || MOST_NEGATIVE_FIXNUM <= hi)
1533 && (TIME_T_MAX >> LO_TIME_BITS <= MOST_POSITIVE_FIXNUM
1534 || hi <= MOST_POSITIVE_FIXNUM)))
1535 time_overflow (); 1527 time_overflow ();
1536
1537 return hi; 1528 return hi;
1538} 1529}
1539 1530
@@ -1595,7 +1586,7 @@ time_arith (Lisp_Object a, Lisp_Object b,
1595 struct lisp_time ta = lisp_time_struct (a, &alen); 1586 struct lisp_time ta = lisp_time_struct (a, &alen);
1596 struct lisp_time tb = lisp_time_struct (b, &blen); 1587 struct lisp_time tb = lisp_time_struct (b, &blen);
1597 struct lisp_time t = op (ta, tb); 1588 struct lisp_time t = op (ta, tb);
1598 if (! (MOST_NEGATIVE_FIXNUM <= t.hi && t.hi <= MOST_POSITIVE_FIXNUM)) 1589 if (FIXNUM_OVERFLOW_P (t.hi))
1599 time_overflow (); 1590 time_overflow ();
1600 Lisp_Object val = Qnil; 1591 Lisp_Object val = Qnil;
1601 1592
@@ -1853,7 +1844,7 @@ decode_time_components (Lisp_Object high, Lisp_Object low, Lisp_Object usec,
1853 1844
1854 if (result) 1845 if (result)
1855 { 1846 {
1856 if (! (MOST_NEGATIVE_FIXNUM <= hi && hi <= MOST_POSITIVE_FIXNUM)) 1847 if (FIXNUM_OVERFLOW_P (hi))
1857 return -1; 1848 return -1;
1858 result->hi = hi; 1849 result->hi = hi;
1859 result->lo = lo; 1850 result->lo = lo;
diff --git a/src/emacs-module.c b/src/emacs-module.c
index 724d24a7768..0e755ef956b 100644
--- a/src/emacs-module.c
+++ b/src/emacs-module.c
@@ -30,7 +30,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
30#include "lisp.h" 30#include "lisp.h"
31#include "dynlib.h" 31#include "dynlib.h"
32#include "coding.h" 32#include "coding.h"
33#include "verify.h" 33
34#include <intprops.h>
35#include <verify.h>
34 36
35 37
36/* Feature tests. */ 38/* Feature tests. */
@@ -424,13 +426,14 @@ module_funcall (emacs_env *env, emacs_value fun, ptrdiff_t nargs,
424 first arg, because that's what Ffuncall takes. */ 426 first arg, because that's what Ffuncall takes. */
425 Lisp_Object *newargs; 427 Lisp_Object *newargs;
426 USE_SAFE_ALLOCA; 428 USE_SAFE_ALLOCA;
427 if (nargs == PTRDIFF_MAX) 429 ptrdiff_t nargs1;
430 if (INT_ADD_WRAPV (nargs, 1, &nargs1))
428 xsignal0 (Qoverflow_error); 431 xsignal0 (Qoverflow_error);
429 SAFE_ALLOCA_LISP (newargs, nargs + 1); 432 SAFE_ALLOCA_LISP (newargs, nargs1);
430 newargs[0] = value_to_lisp (fun); 433 newargs[0] = value_to_lisp (fun);
431 for (ptrdiff_t i = 0; i < nargs; i++) 434 for (ptrdiff_t i = 0; i < nargs; i++)
432 newargs[1 + i] = value_to_lisp (args[i]); 435 newargs[1 + i] = value_to_lisp (args[i]);
433 emacs_value result = lisp_to_value (Ffuncall (nargs + 1, newargs)); 436 emacs_value result = lisp_to_value (Ffuncall (nargs1, newargs));
434 SAFE_FREE (); 437 SAFE_FREE ();
435 return result; 438 return result;
436} 439}
@@ -665,7 +668,7 @@ DEFUN ("module-load", Fmodule_load, Smodule_load, 1, 1, 0,
665 668
666 if (r != 0) 669 if (r != 0)
667 { 670 {
668 if (! (MOST_NEGATIVE_FIXNUM <= r && r <= MOST_POSITIVE_FIXNUM)) 671 if (FIXNUM_OVERFLOW_P (r))
669 xsignal0 (Qoverflow_error); 672 xsignal0 (Qoverflow_error);
670 xsignal2 (Qmodule_load_failed, file, make_number (r)); 673 xsignal2 (Qmodule_load_failed, file, make_number (r));
671 } 674 }
diff --git a/src/font.c b/src/font.c
index 144ba07c42a..f2800633b62 100644
--- a/src/font.c
+++ b/src/font.c
@@ -264,14 +264,13 @@ font_intern_prop (const char *str, ptrdiff_t len, bool force_symbol)
264 break; 264 break;
265 if (i == len) 265 if (i == len)
266 { 266 {
267 EMACS_INT n;
268
269 i = 0; 267 i = 0;
270 for (n = 0; (n += str[i++] - '0') <= MOST_POSITIVE_FIXNUM; n *= 10) 268 for (EMACS_INT n = 0;
269 (n += str[i++] - '0') <= MOST_POSITIVE_FIXNUM; )
271 { 270 {
272 if (i == len) 271 if (i == len)
273 return make_number (n); 272 return make_number (n);
274 if (MOST_POSITIVE_FIXNUM / 10 < n) 273 if (INT_MULTIPLY_WRAPV (n, 10, &n))
275 break; 274 break;
276 } 275 }
277 276
diff --git a/src/keyboard.c b/src/keyboard.c
index b8bc3610eb0..ca40c6e7ad0 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -10058,11 +10058,9 @@ DEFUN ("recursion-depth", Frecursion_depth, Srecursion_depth, 0, 0, 0,
10058 doc: /* Return the current depth in recursive edits. */) 10058 doc: /* Return the current depth in recursive edits. */)
10059 (void) 10059 (void)
10060{ 10060{
10061 Lisp_Object temp; 10061 EMACS_INT sum;
10062 /* Wrap around reliably on integer overflow. */ 10062 INT_ADD_WRAPV (command_loop_level, minibuf_level, &sum);
10063 EMACS_INT sum = (command_loop_level & INTMASK) + (minibuf_level & INTMASK); 10063 return make_number (sum);
10064 XSETINT (temp, sum);
10065 return temp;
10066} 10064}
10067 10065
10068DEFUN ("open-dribble-file", Fopen_dribble_file, Sopen_dribble_file, 1, 1, 10066DEFUN ("open-dribble-file", Fopen_dribble_file, Sopen_dribble_file, 1, 1,
diff --git a/src/lread.c b/src/lread.c
index dc7c00bbfae..d3413d16cea 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -2894,19 +2894,17 @@ read1 (Lisp_Object readcharfun, int *pch, bool first_in_list)
2894 { 2894 {
2895 EMACS_INT n = 0; 2895 EMACS_INT n = 0;
2896 Lisp_Object tem; 2896 Lisp_Object tem;
2897 bool overflow = false;
2897 2898
2898 /* Read a non-negative integer. */ 2899 /* Read a non-negative integer. */
2899 while (c >= '0' && c <= '9') 2900 while (c >= '0' && c <= '9')
2900 { 2901 {
2901 if (MOST_POSITIVE_FIXNUM / 10 < n 2902 overflow |= INT_MULTIPLY_WRAPV (n, 10, &n);
2902 || MOST_POSITIVE_FIXNUM < n * 10 + c - '0') 2903 overflow |= INT_ADD_WRAPV (n, c - '0', &n);
2903 n = MOST_POSITIVE_FIXNUM + 1;
2904 else
2905 n = n * 10 + c - '0';
2906 c = READCHAR; 2904 c = READCHAR;
2907 } 2905 }
2908 2906
2909 if (n <= MOST_POSITIVE_FIXNUM) 2907 if (!overflow && n <= MOST_POSITIVE_FIXNUM)
2910 { 2908 {
2911 if (c == 'r' || c == 'R') 2909 if (c == 'r' || c == 'R')
2912 return read_integer (readcharfun, n); 2910 return read_integer (readcharfun, n);
diff --git a/src/xdisp.c b/src/xdisp.c
index 4bf1470e46c..13af87f953c 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -23448,6 +23448,16 @@ decode_mode_spec_coding (Lisp_Object coding_system, char *buf, bool eol_flag)
23448 return buf; 23448 return buf;
23449} 23449}
23450 23450
23451/* Return the approximate percentage N is of D (rounding upward), or 99,
23452 whichever is less. Assume 0 < D and 0 <= N <= D * INT_MAX / 100. */
23453
23454static int
23455percent99 (ptrdiff_t n, ptrdiff_t d)
23456{
23457 int percent = (d - 1 + 100.0 * n) / d;
23458 return min (percent, 99);
23459}
23460
23451/* Return a string for the output of a mode line %-spec for window W, 23461/* Return a string for the output of a mode line %-spec for window W,
23452 generated by character C. FIELD_WIDTH > 0 means pad the string 23462 generated by character C. FIELD_WIDTH > 0 means pad the string
23453 returned with spaces to that value. Return a Lisp string in 23463 returned with spaces to that value. Return a Lisp string in
@@ -23735,29 +23745,17 @@ decode_mode_spec (struct window *w, register int c, int field_width,
23735 case 'p': 23745 case 'p':
23736 { 23746 {
23737 ptrdiff_t pos = marker_position (w->start); 23747 ptrdiff_t pos = marker_position (w->start);
23738 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b); 23748 ptrdiff_t begv = BUF_BEGV (b);
23749 ptrdiff_t zv = BUF_ZV (b);
23739 23750
23740 if (w->window_end_pos <= BUF_Z (b) - BUF_ZV (b)) 23751 if (w->window_end_pos <= BUF_Z (b) - zv)
23741 { 23752 return pos <= begv ? "All" : "Bottom";
23742 if (pos <= BUF_BEGV (b)) 23753 else if (pos <= begv)
23743 return "All";
23744 else
23745 return "Bottom";
23746 }
23747 else if (pos <= BUF_BEGV (b))
23748 return "Top"; 23754 return "Top";
23749 else 23755 else
23750 { 23756 {
23751 if (total > 1000000) 23757 sprintf (decode_mode_spec_buf, "%2d%%",
23752 /* Do it differently for a large value, to avoid overflow. */ 23758 percent99 (pos - begv, zv - begv));
23753 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
23754 else
23755 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
23756 /* We can't normally display a 3-digit number,
23757 so get us a 2-digit number that is close. */
23758 if (total == 100)
23759 total = 99;
23760 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
23761 return decode_mode_spec_buf; 23759 return decode_mode_spec_buf;
23762 } 23760 }
23763 } 23761 }
@@ -23767,30 +23765,16 @@ decode_mode_spec (struct window *w, register int c, int field_width,
23767 { 23765 {
23768 ptrdiff_t toppos = marker_position (w->start); 23766 ptrdiff_t toppos = marker_position (w->start);
23769 ptrdiff_t botpos = BUF_Z (b) - w->window_end_pos; 23767 ptrdiff_t botpos = BUF_Z (b) - w->window_end_pos;
23770 ptrdiff_t total = BUF_ZV (b) - BUF_BEGV (b); 23768 ptrdiff_t begv = BUF_BEGV (b);
23769 ptrdiff_t zv = BUF_ZV (b);
23771 23770
23772 if (botpos >= BUF_ZV (b)) 23771 if (zv <= botpos)
23773 { 23772 return toppos <= begv ? "All" : "Bottom";
23774 if (toppos <= BUF_BEGV (b))
23775 return "All";
23776 else
23777 return "Bottom";
23778 }
23779 else 23773 else
23780 { 23774 {
23781 if (total > 1000000) 23775 sprintf (decode_mode_spec_buf,
23782 /* Do it differently for a large value, to avoid overflow. */ 23776 &"Top%2d%%"[begv < toppos ? sizeof "Top" - 1 : 0],
23783 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100); 23777 percent99 (botpos - begv, zv - begv));
23784 else
23785 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
23786 /* We can't normally display a 3-digit number,
23787 so get us a 2-digit number that is close. */
23788 if (total == 100)
23789 total = 99;
23790 if (toppos <= BUF_BEGV (b))
23791 sprintf (decode_mode_spec_buf, "Top%2"pD"d%%", total);
23792 else
23793 sprintf (decode_mode_spec_buf, "%2"pD"d%%", total);
23794 return decode_mode_spec_buf; 23778 return decode_mode_spec_buf;
23795 } 23779 }
23796 } 23780 }