diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2013-01-19 10:26:26 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2013-01-19 10:26:26 (GMT) |
commit | 441d30fac7f4037e4a79e4ada873de3b6f6e5a26 (patch) | |
tree | a406cb41f1b78476445786f408b95b1cd0bdb7a6 /Objects | |
parent | ff12fae80e15ad29ae2557d23e70f6ff9365b31f (diff) | |
download | cpython-441d30fac7f4037e4a79e4ada873de3b6f6e5a26.zip cpython-441d30fac7f4037e4a79e4ada873de3b6f6e5a26.tar.gz cpython-441d30fac7f4037e4a79e4ada873de3b6f6e5a26.tar.bz2 |
Issue #15989: Fix several occurrences of integer overflow
when result of PyLong_AsLong() narrowed to int without checks.
This is a backport of changesets 13e2e44db99d and 525407d89277.
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/fileobject.c | 4 | ||||
-rw-r--r-- | Objects/longobject.c | 18 | ||||
-rw-r--r-- | Objects/unicodeobject.c | 4 |
3 files changed, 22 insertions, 4 deletions
diff --git a/Objects/fileobject.c b/Objects/fileobject.c index d20f196..500883e 100644 --- a/Objects/fileobject.c +++ b/Objects/fileobject.c @@ -200,7 +200,7 @@ PyObject_AsFileDescriptor(PyObject *o) PyObject *meth; if (PyLong_Check(o)) { - fd = PyLong_AsLong(o); + fd = _PyLong_AsInt(o); } else if ((meth = PyObject_GetAttrString(o, "fileno")) != NULL) { @@ -210,7 +210,7 @@ PyObject_AsFileDescriptor(PyObject *o) return -1; if (PyLong_Check(fno)) { - fd = PyLong_AsLong(fno); + fd = _PyLong_AsInt(fno); Py_DECREF(fno); } else { diff --git a/Objects/longobject.c b/Objects/longobject.c index 51da329..9ca7b65 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -424,6 +424,24 @@ PyLong_AsLong(PyObject *obj) return result; } +/* Get a C int from a long int object or any object that has an __int__ + method. Return -1 and set an error if overflow occurs. */ + +int +_PyLong_AsInt(PyObject *obj) +{ + int overflow; + long result = PyLong_AsLongAndOverflow(obj, &overflow); + if (overflow || result > INT_MAX || result < INT_MIN) { + /* XXX: could be cute and give a different + message for overflow == -1 */ + PyErr_SetString(PyExc_OverflowError, + "Python int too large to convert to C int"); + return -1; + } + return (int)result; +} + /* Get a Py_ssize_t from a long int object. Returns -1 and sets an error condition if overflow occurs. */ diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index e1df874..80a70b6 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -9640,7 +9640,7 @@ PyObject *PyUnicode_Format(PyObject *format, "* wants int"); goto onError; } - width = PyLong_AsLong(v); + width = PyLong_AsSsize_t(v); if (width == -1 && PyErr_Occurred()) goto onError; if (width < 0) { @@ -9677,7 +9677,7 @@ PyObject *PyUnicode_Format(PyObject *format, "* wants int"); goto onError; } - prec = PyLong_AsLong(v); + prec = _PyLong_AsInt(v); if (prec == -1 && PyErr_Occurred()) goto onError; if (prec < 0) |