mirror of
https://github.com/python/cpython.git
synced 2025-08-22 17:55:18 +00:00
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:
parent
c6f2f884b4
commit
4b63c21d6f
19 changed files with 187 additions and 113 deletions
|
@ -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) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue