Forward-port of r52136: a review of overflow-detecting code.

* unified the way intobject, longobject and mystrtoul handle
  values around -sys.maxint-1.

* in general, trying to entierely avoid overflows in any computation
  involving signed ints or longs is extremely involved.  Fixed a few
  simple cases where a compiler might be too clever (but that's all
  guesswork).

* more overflow checks against bad data in marshal.c.

* 2.5 specific: fixed a number of places that were still confusing int
  and Py_ssize_t.  Some of them could potentially have caused
  "real-world" breakage.

* list.pop(x): fixing overflow issues on x was messy.  I just reverted
  to PyArg_ParseTuple("n"), which does the right thing.  (An obscure
  test was trying to give a Decimal to list.pop()... doesn't make
  sense any more IMHO)

* trying to write a few tests...
This commit is contained in:
Armin Rigo 2006-10-04 11:44:06 +00:00
parent c6f2f884b4
commit 4b63c21d6f
19 changed files with 187 additions and 113 deletions

View file

@ -804,10 +804,22 @@ string_print(PyStringObject *op, FILE *fp, int flags)
return ret;
}
if (flags & Py_PRINT_RAW) {
char *data = op->ob_sval;
Py_ssize_t size = op->ob_size;
while (size > INT_MAX) {
/* Very long strings cannot be written atomically.
* But don't write exactly INT_MAX bytes at a time
* to avoid memory aligment issues.
*/
const int chunk_size = INT_MAX & ~0x3FFF;
fwrite(data, 1, chunk_size, fp);
data += chunk_size;
size -= chunk_size;
}
#ifdef __VMS
if (op->ob_size) fwrite(op->ob_sval, (int) op->ob_size, 1, fp);
if (size) fwrite(data, (int)size, 1, fp);
#else
fwrite(op->ob_sval, 1, (int) op->ob_size, fp);
fwrite(data, 1, (int)size, fp);
#endif
return 0;
}
@ -844,7 +856,7 @@ PyString_Repr(PyObject *obj, int smartquotes)
register PyStringObject* op = (PyStringObject*) obj;
size_t newsize = 2 + 4 * op->ob_size;
PyObject *v;
if (newsize > PY_SSIZE_T_MAX) {
if (newsize > PY_SSIZE_T_MAX || newsize / 4 != op->ob_size) {
PyErr_SetString(PyExc_OverflowError,
"string is too large to make repr");
}
@ -4237,7 +4249,7 @@ _PyString_FormatLong(PyObject *val, int flags, int prec, int type,
return NULL;
}
llen = PyString_Size(result);
if (llen > PY_SSIZE_T_MAX) {
if (llen > INT_MAX) {
PyErr_SetString(PyExc_ValueError, "string too large in _PyString_FormatLong");
return NULL;
}
@ -4726,9 +4738,10 @@ PyString_Format(PyObject *format, PyObject *args)
default:
PyErr_Format(PyExc_ValueError,
"unsupported format character '%c' (0x%x) "
"at index %i",
"at index %zd",
c, c,
(int)(fmt - 1 - PyString_AsString(format)));
(Py_ssize_t)(fmt - 1 -
PyString_AsString(format)));
goto error;
}
if (sign) {