Issue #9530: Fix undefined behaviour due to signed overflow in Python/formatter_unicode.c.

This commit is contained in:
Mark Dickinson 2011-12-01 15:27:04 +00:00
parent 0a54cf12a0
commit 47862d4c0e
1 changed files with 7 additions and 9 deletions

View File

@ -51,7 +51,7 @@ static int
get_integer(PyObject *str, Py_ssize_t *pos, Py_ssize_t end, get_integer(PyObject *str, Py_ssize_t *pos, Py_ssize_t end,
Py_ssize_t *result) Py_ssize_t *result)
{ {
Py_ssize_t accumulator, digitval, oldaccumulator; Py_ssize_t accumulator, digitval;
int numdigits; int numdigits;
accumulator = numdigits = 0; accumulator = numdigits = 0;
for (;;(*pos)++, numdigits++) { for (;;(*pos)++, numdigits++) {
@ -61,19 +61,17 @@ get_integer(PyObject *str, Py_ssize_t *pos, Py_ssize_t end,
if (digitval < 0) if (digitval < 0)
break; break;
/* /*
This trick was copied from old Unicode format code. It's cute, Detect possible overflow before it happens:
but would really suck on an old machine with a slow divide
implementation. Fortunately, in the normal case we do not accumulator * 10 + digitval > PY_SSIZE_T_MAX if and only if
expect too many digits. accumulator > (PY_SSIZE_T_MAX - digitval) / 10.
*/ */
oldaccumulator = accumulator; if (accumulator > (PY_SSIZE_T_MAX - digitval) / 10) {
accumulator *= 10;
if ((accumulator+10)/10 != oldaccumulator+1) {
PyErr_Format(PyExc_ValueError, PyErr_Format(PyExc_ValueError,
"Too many decimal digits in format string"); "Too many decimal digits in format string");
return -1; return -1;
} }
accumulator += digitval; accumulator = accumulator * 10 + digitval;
} }
*result = accumulator; *result = accumulator;
return numdigits; return numdigits;