aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert2011-06-22 17:55:55 -0700
committerPaul Eggert2011-06-22 17:55:55 -0700
commit8b9ac8b4a241b0f3be53e6438e69b227aac20d24 (patch)
tree54a83c4d055dad72e8521ce1cf4710c552418042 /src
parent7fcccf1efe3d4bc6182253ec0b1b5fd409fdd242 (diff)
downloademacs-8b9ac8b4a241b0f3be53e6438e69b227aac20d24.tar.gz
emacs-8b9ac8b4a241b0f3be53e6438e69b227aac20d24.zip
* lread.c: Integer overflow fixes.
(read_integer): Radix is now EMACS_INT, not int, to improve quality of diagnostics for out-of-range radices. Calculate buffer size correctly for out-of-range radices. (read1): Check for integer overflow in radices, and in read-circle numbers.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog7
-rw-r--r--src/lread.c79
2 files changed, 53 insertions, 33 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 7f174bf0a21..96e6741f11f 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,12 @@
12011-06-23 Paul Eggert <eggert@cs.ucla.edu> 12011-06-23 Paul Eggert <eggert@cs.ucla.edu>
2 2
3 * lread.c: Integer overflow fixes.
4 (read_integer): Radix is now EMACS_INT, not int,
5 to improve quality of diagnostics for out-of-range radices.
6 Calculate buffer size correctly for out-of-range radices.
7 (read1): Check for integer overflow in radices, and in
8 read-circle numbers.
9
3 * image.c (cache_image): Check for size arithmetic overflow. 10 * image.c (cache_image): Check for size arithmetic overflow.
4 11
52011-06-22 Paul Eggert <eggert@cs.ucla.edu> 122011-06-22 Paul Eggert <eggert@cs.ucla.edu>
diff --git a/src/lread.c b/src/lread.c
index a2f78f848ae..2f1c05c5aa1 100644
--- a/src/lread.c
+++ b/src/lread.c
@@ -2277,10 +2277,12 @@ digit_to_number (int character, int base)
2277 range. */ 2277 range. */
2278 2278
2279static Lisp_Object 2279static Lisp_Object
2280read_integer (Lisp_Object readcharfun, int radix) 2280read_integer (Lisp_Object readcharfun, EMACS_INT radix)
2281{ 2281{
2282 /* Room for sign, leading 0, other digits, trailing null byte. */ 2282 /* Room for sign, leading 0, other digits, trailing null byte.
2283 char buf[1 + 1 + sizeof (uintmax_t) * CHAR_BIT + 1]; 2283 Also, room for invalid syntax diagnostic. */
2284 char buf[max (1 + 1 + sizeof (uintmax_t) * CHAR_BIT + 1,
2285 sizeof "integer, radix " + INT_STRLEN_BOUND (EMACS_INT))];
2284 2286
2285 int valid = -1; /* 1 if valid, 0 if not, -1 if incomplete. */ 2287 int valid = -1; /* 1 if valid, 0 if not, -1 if incomplete. */
2286 2288
@@ -2332,7 +2334,7 @@ read_integer (Lisp_Object readcharfun, int radix)
2332 2334
2333 if (! valid) 2335 if (! valid)
2334 { 2336 {
2335 sprintf (buf, "integer, radix %d", radix); 2337 sprintf (buf, "integer, radix %"pI"d", radix);
2336 invalid_syntax (buf); 2338 invalid_syntax (buf);
2337 } 2339 }
2338 2340
@@ -2663,49 +2665,60 @@ read1 (register Lisp_Object readcharfun, int *pch, int first_in_list)
2663 /* Reader forms that can reuse previously read objects. */ 2665 /* Reader forms that can reuse previously read objects. */
2664 if (c >= '0' && c <= '9') 2666 if (c >= '0' && c <= '9')
2665 { 2667 {
2666 int n = 0; 2668 EMACS_INT n = 0;
2667 Lisp_Object tem; 2669 Lisp_Object tem;
2668 2670
2669 /* Read a non-negative integer. */ 2671 /* Read a non-negative integer. */
2670 while (c >= '0' && c <= '9') 2672 while (c >= '0' && c <= '9')
2671 { 2673 {
2672 n *= 10; 2674 if (MOST_POSITIVE_FIXNUM / 10 < n
2673 n += c - '0'; 2675 || MOST_POSITIVE_FIXNUM < n * 10 + c - '0')
2676 n = MOST_POSITIVE_FIXNUM + 1;
2677 else
2678 n = n * 10 + c - '0';
2674 c = READCHAR; 2679 c = READCHAR;
2675 } 2680 }
2676 /* #n=object returns object, but associates it with n for #n#. */ 2681
2677 if (c == '=' && !NILP (Vread_circle)) 2682 if (n <= MOST_POSITIVE_FIXNUM)
2678 { 2683 {
2679 /* Make a placeholder for #n# to use temporarily */ 2684 if (c == 'r' || c == 'R')
2680 Lisp_Object placeholder; 2685 return read_integer (readcharfun, n);
2681 Lisp_Object cell;
2682 2686
2683 placeholder = Fcons (Qnil, Qnil); 2687 if (! NILP (Vread_circle))
2684 cell = Fcons (make_number (n), placeholder); 2688 {
2685 read_objects = Fcons (cell, read_objects); 2689 /* #n=object returns object, but associates it with
2690 n for #n#. */
2691 if (c == '=')
2692 {
2693 /* Make a placeholder for #n# to use temporarily */
2694 Lisp_Object placeholder;
2695 Lisp_Object cell;
2686 2696
2687 /* Read the object itself. */ 2697 placeholder = Fcons (Qnil, Qnil);
2688 tem = read0 (readcharfun); 2698 cell = Fcons (make_number (n), placeholder);
2699 read_objects = Fcons (cell, read_objects);
2689 2700
2690 /* Now put it everywhere the placeholder was... */ 2701 /* Read the object itself. */
2691 substitute_object_in_subtree (tem, placeholder); 2702 tem = read0 (readcharfun);
2692 2703
2693 /* ...and #n# will use the real value from now on. */ 2704 /* Now put it everywhere the placeholder was... */
2694 Fsetcdr (cell, tem); 2705 substitute_object_in_subtree (tem, placeholder);
2695 2706
2696 return tem; 2707 /* ...and #n# will use the real value from now on. */
2697 } 2708 Fsetcdr (cell, tem);
2698 /* #n# returns a previously read object. */
2699 if (c == '#' && !NILP (Vread_circle))
2700 {
2701 tem = Fassq (make_number (n), read_objects);
2702 if (CONSP (tem))
2703 return XCDR (tem);
2704 /* Fall through to error message. */
2705 }
2706 else if (c == 'r' || c == 'R')
2707 return read_integer (readcharfun, n);
2708 2709
2710 return tem;
2711 }
2712
2713 /* #n# returns a previously read object. */
2714 if (c == '#')
2715 {
2716 tem = Fassq (make_number (n), read_objects);
2717 if (CONSP (tem))
2718 return XCDR (tem);
2719 }
2720 }
2721 }
2709 /* Fall through to error message. */ 2722 /* Fall through to error message. */
2710 } 2723 }
2711 else if (c == 'x' || c == 'X') 2724 else if (c == 'x' || c == 'X')