Commit 8b9ac8b4 authored by Paul Eggert's avatar Paul Eggert
Browse files

* 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.
parent 7fcccf1e
2011-06-23 Paul Eggert <eggert@cs.ucla.edu>
* 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.
* image.c (cache_image): Check for size arithmetic overflow.
2011-06-22 Paul Eggert <eggert@cs.ucla.edu>
......
......@@ -2277,10 +2277,12 @@ digit_to_number (int character, int base)
range. */
static Lisp_Object
read_integer (Lisp_Object readcharfun, int radix)
read_integer (Lisp_Object readcharfun, EMACS_INT radix)
{
/* Room for sign, leading 0, other digits, trailing null byte. */
char buf[1 + 1 + sizeof (uintmax_t) * CHAR_BIT + 1];
/* Room for sign, leading 0, other digits, trailing null byte.
Also, room for invalid syntax diagnostic. */
char buf[max (1 + 1 + sizeof (uintmax_t) * CHAR_BIT + 1,
sizeof "integer, radix " + INT_STRLEN_BOUND (EMACS_INT))];
int valid = -1; /* 1 if valid, 0 if not, -1 if incomplete. */
......@@ -2332,7 +2334,7 @@ read_integer (Lisp_Object readcharfun, int radix)
if (! valid)
{
sprintf (buf, "integer, radix %d", radix);
sprintf (buf, "integer, radix %"pI"d", radix);
invalid_syntax (buf);
}
......@@ -2663,49 +2665,60 @@ read1 (register Lisp_Object readcharfun, int *pch, int first_in_list)
/* Reader forms that can reuse previously read objects. */
if (c >= '0' && c <= '9')
{
int n = 0;
EMACS_INT n = 0;
Lisp_Object tem;
/* Read a non-negative integer. */
while (c >= '0' && c <= '9')
{
n *= 10;
n += c - '0';
if (MOST_POSITIVE_FIXNUM / 10 < n
|| MOST_POSITIVE_FIXNUM < n * 10 + c - '0')
n = MOST_POSITIVE_FIXNUM + 1;
else
n = n * 10 + c - '0';
c = READCHAR;
}
/* #n=object returns object, but associates it with n for #n#. */
if (c == '=' && !NILP (Vread_circle))
if (n <= MOST_POSITIVE_FIXNUM)
{
/* Make a placeholder for #n# to use temporarily */
Lisp_Object placeholder;
Lisp_Object cell;
if (c == 'r' || c == 'R')
return read_integer (readcharfun, n);
placeholder = Fcons (Qnil, Qnil);
cell = Fcons (make_number (n), placeholder);
read_objects = Fcons (cell, read_objects);
if (! NILP (Vread_circle))
{
/* #n=object returns object, but associates it with
n for #n#. */
if (c == '=')
{
/* Make a placeholder for #n# to use temporarily */
Lisp_Object placeholder;
Lisp_Object cell;
/* Read the object itself. */
tem = read0 (readcharfun);
placeholder = Fcons (Qnil, Qnil);
cell = Fcons (make_number (n), placeholder);
read_objects = Fcons (cell, read_objects);
/* Now put it everywhere the placeholder was... */
substitute_object_in_subtree (tem, placeholder);
/* Read the object itself. */
tem = read0 (readcharfun);
/* ...and #n# will use the real value from now on. */
Fsetcdr (cell, tem);
/* Now put it everywhere the placeholder was... */
substitute_object_in_subtree (tem, placeholder);
return tem;
}
/* #n# returns a previously read object. */
if (c == '#' && !NILP (Vread_circle))
{
tem = Fassq (make_number (n), read_objects);
if (CONSP (tem))
return XCDR (tem);
/* Fall through to error message. */
}
else if (c == 'r' || c == 'R')
return read_integer (readcharfun, n);
/* ...and #n# will use the real value from now on. */
Fsetcdr (cell, tem);
return tem;
}
/* #n# returns a previously read object. */
if (c == '#')
{
tem = Fassq (make_number (n), read_objects);
if (CONSP (tem))
return XCDR (tem);
}
}
}
/* Fall through to error message. */
}
else if (c == 'x' || c == 'X')
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment