Mercurial > cpython-lru_cache-weakref
diff Python/marshal.c @ 39990:a9b1f404e88b 2.4
A review of overflow-detecting code in the 2.4 branch.
* 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.
| author | Armin Rigo <arigo@tunes.org> |
|---|---|
| date | Wed, 04 Oct 2006 10:13:32 +0000 |
| parents | 6fb46e87d5f9 |
| children | 2a46b76beb9e |
line wrap: on
line diff
--- a/Python/marshal.c Wed Oct 04 09:18:51 2006 +0000 +++ b/Python/marshal.c Wed Oct 04 10:13:32 2006 +0000 @@ -451,6 +451,11 @@ int size; PyLongObject *ob; n = r_long(p); + if (n < -INT_MAX || n > INT_MAX) { + PyErr_SetString(PyExc_ValueError, + "bad marshal data"); + return NULL; + } size = n<0 ? -n : n; ob = _PyLong_New(size); if (ob == NULL) @@ -518,7 +523,7 @@ case TYPE_INTERNED: case TYPE_STRING: n = r_long(p); - if (n < 0) { + if (n < 0 || n > INT_MAX) { PyErr_SetString(PyExc_ValueError, "bad marshal data"); return NULL; } @@ -539,6 +544,10 @@ case TYPE_STRINGREF: n = r_long(p); + if (n < 0 || n >= PyList_GET_SIZE(p->strings)) { + PyErr_SetString(PyExc_ValueError, "bad marshal data"); + return NULL; + } v = PyList_GET_ITEM(p->strings, n); Py_INCREF(v); return v; @@ -549,7 +558,7 @@ char *buffer; n = r_long(p); - if (n < 0) { + if (n < 0 || n > INT_MAX) { PyErr_SetString(PyExc_ValueError, "bad marshal data"); return NULL; } @@ -570,7 +579,7 @@ case TYPE_TUPLE: n = r_long(p); - if (n < 0) { + if (n < 0 || n > INT_MAX) { PyErr_SetString(PyExc_ValueError, "bad marshal data"); return NULL; } @@ -593,7 +602,7 @@ case TYPE_LIST: n = r_long(p); - if (n < 0) { + if (n < 0 || n > INT_MAX) { PyErr_SetString(PyExc_ValueError, "bad marshal data"); return NULL; } @@ -643,10 +652,11 @@ return NULL; } else { - int argcount = r_long(p); - int nlocals = r_long(p); - int stacksize = r_long(p); - int flags = r_long(p); + /* XXX ignore long->int overflows for now */ + int argcount = (int)r_long(p); + int nlocals = (int)r_long(p); + int stacksize = (int)r_long(p); + int flags = (int)r_long(p); PyObject *code = r_object(p); PyObject *consts = r_object(p); PyObject *names = r_object(p); @@ -655,7 +665,7 @@ PyObject *cellvars = r_object(p); PyObject *filename = r_object(p); PyObject *name = r_object(p); - int firstlineno = r_long(p); + int firstlineno = (int)r_long(p); PyObject *lnotab = r_object(p); if (!PyErr_Occurred()) { @@ -821,10 +831,16 @@ wf.strings = (version > 0) ? PyDict_New() : NULL; w_object(x, &wf); Py_XDECREF(wf.strings); - if (wf.str != NULL) - _PyString_Resize(&wf.str, - (int) (wf.ptr - - PyString_AS_STRING((PyStringObject *)wf.str))); + if (wf.str != NULL) { + char *base = PyString_AS_STRING((PyStringObject *)wf.str); + if (wf.ptr - base > INT_MAX) { + Py_DECREF(wf.str); + PyErr_SetString(PyExc_OverflowError, + "too much marshall data for a string"); + return NULL; + } + _PyString_Resize(&wf.str, (int)(wf.ptr - base)); + } if (wf.error) { Py_XDECREF(wf.str); PyErr_SetString(PyExc_ValueError,
