Serhiy Storchaka added the comment:

Here is a patch (for 3.3). I added private _PyLong_AsInt and where possible I 
have tried to use the appropriate function.

----------
keywords: +patch
Added file: http://bugs.python.org/file27246/long_aslong_overflow.patch

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue15989>
_______________________________________
diff -r 59a2807872d5 Include/longobject.h
--- a/Include/longobject.h      Fri Sep 21 17:29:20 2012 +0300
+++ b/Include/longobject.h      Fri Sep 21 19:21:25 2012 +0300
@@ -26,6 +26,9 @@
 PyAPI_FUNC(size_t) PyLong_AsSize_t(PyObject *);
 PyAPI_FUNC(unsigned long) PyLong_AsUnsignedLong(PyObject *);
 PyAPI_FUNC(unsigned long) PyLong_AsUnsignedLongMask(PyObject *);
+#ifndef Py_LIMITED_API
+PyAPI_FUNC(int) _PyLong_AsInt(PyObject *);
+#endif
 PyAPI_FUNC(PyObject *) PyLong_GetInfo(void);
 
 /* It may be useful in the future. I've added it in the PyInt -> PyLong
diff -r 59a2807872d5 Modules/_ctypes/stgdict.c
--- a/Modules/_ctypes/stgdict.c Fri Sep 21 17:29:20 2012 +0300
+++ b/Modules/_ctypes/stgdict.c Fri Sep 21 19:21:25 2012 +0300
@@ -335,7 +335,7 @@
 
     isPacked = PyObject_GetAttrString(type, "_pack_");
     if (isPacked) {
-        pack = PyLong_AsLong(isPacked);
+        pack = _PyLong_AsInt(isPacked);
         if (pack < 0 || PyErr_Occurred()) {
             Py_XDECREF(isPacked);
             PyErr_SetString(PyExc_ValueError,
diff -r 59a2807872d5 Modules/_datetimemodule.c
--- a/Modules/_datetimemodule.c Fri Sep 21 17:29:20 2012 +0300
+++ b/Modules/_datetimemodule.c Fri Sep 21 19:21:25 2012 +0300
@@ -4717,7 +4717,7 @@
     if (seconds == NULL)
         goto error;
     Py_DECREF(delta);
-    timestamp = PyLong_AsLong(seconds);
+    timestamp = _PyLong_AsTime_t(seconds);
     Py_DECREF(seconds);
     if (timestamp == -1 && PyErr_Occurred())
         return NULL;
diff -r 59a2807872d5 Modules/_io/_iomodule.c
--- a/Modules/_io/_iomodule.c   Fri Sep 21 17:29:20 2012 +0300
+++ b/Modules/_io/_iomodule.c   Fri Sep 21 19:21:25 2012 +0300
@@ -358,9 +358,9 @@
         PyObject *res = _PyObject_CallMethodId(raw, &PyId_isatty, NULL);
         if (res == NULL)
             goto error;
-        isatty = PyLong_AsLong(res);
+        isatty = PyObject_IsTrue(res);
         Py_DECREF(res);
-        if (isatty == -1 && PyErr_Occurred())
+        if (isatty < 0)
             goto error;
     }
 
@@ -376,12 +376,12 @@
 #ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
         {
             struct stat st;
-            long fileno;
+            int fileno;
             PyObject *res = _PyObject_CallMethodId(raw, &PyId_fileno, NULL);
             if (res == NULL)
                 goto error;
 
-            fileno = PyLong_AsLong(res);
+            fileno = _PyLong_AsInt(res);
             Py_DECREF(res);
             if (fileno == -1 && PyErr_Occurred())
                 goto error;
diff -r 59a2807872d5 Modules/_io/fileio.c
--- a/Modules/_io/fileio.c      Fri Sep 21 17:29:20 2012 +0300
+++ b/Modules/_io/fileio.c      Fri Sep 21 19:21:25 2012 +0300
@@ -244,7 +244,7 @@
         return -1;
     }
 
-    fd = PyLong_AsLong(nameobj);
+    fd = _PyLong_AsInt(nameobj);
     if (fd < 0) {
         if (!PyErr_Occurred()) {
             PyErr_SetString(PyExc_ValueError,
@@ -382,7 +382,7 @@
                 goto error;
             }
 
-            self->fd = PyLong_AsLong(fdobj);
+            self->fd = _PyLong_AsInt(fdobj);
             Py_DECREF(fdobj);
             if (self->fd == -1) {
                 goto error;
diff -r 59a2807872d5 Modules/_io/textio.c
--- a/Modules/_io/textio.c      Fri Sep 21 17:29:20 2012 +0300
+++ b/Modules/_io/textio.c      Fri Sep 21 19:21:25 2012 +0300
@@ -881,7 +881,7 @@
             }
         }
         else {
-            int fd = (int) PyLong_AsLong(fileno);
+            int fd = _PyLong_AsInt(fileno);
             Py_DECREF(fileno);
             if (fd == -1 && PyErr_Occurred()) {
                 goto error;
diff -r 59a2807872d5 Modules/_sqlite/connection.c
--- a/Modules/_sqlite/connection.c      Fri Sep 21 17:29:20 2012 +0300
+++ b/Modules/_sqlite/connection.c      Fri Sep 21 19:21:25 2012 +0300
@@ -859,7 +859,7 @@
         rc = SQLITE_DENY;
     } else {
         if (PyLong_Check(ret)) {
-            rc = (int)PyLong_AsLong(ret);
+            rc = _PyLong_AsInt(ret);
         } else {
             rc = SQLITE_DENY;
         }
@@ -1350,7 +1350,7 @@
         goto finally;
     }
 
-    result = PyLong_AsLong(retval);
+    result = _PyLong_AsInt(retval);
     if (PyErr_Occurred()) {
         result = 0;
     }
diff -r 59a2807872d5 Modules/grpmodule.c
--- a/Modules/grpmodule.c       Fri Sep 21 17:29:20 2012 +0300
+++ b/Modules/grpmodule.c       Fri Sep 21 19:21:25 2012 +0300
@@ -85,16 +85,23 @@
 grp_getgrgid(PyObject *self, PyObject *pyo_id)
 {
     PyObject *py_int_id;
-    unsigned int gid;
+    unsigned long gid;
     struct group *p;
 
     py_int_id = PyNumber_Long(pyo_id);
     if (!py_int_id)
             return NULL;
-    gid = PyLong_AS_LONG(py_int_id);
+    gid = PyLong_AsUnsignedLong(py_int_id);
     Py_DECREF(py_int_id);
+    if (gid == (unsigned long)-1 && PyErr_Occurred())
+        return NULL;
+    if ((unsigned long)(gid_t)gid != gid) {
+        PyErr_SetString(PyExc_OverflowError,
+                        "Python int too large to convert to gid_t");
+        return NULL;
+    }
 
-    if ((p = getgrgid(gid)) == NULL) {
+    if ((p = getgrgid((gid_t)gid)) == NULL) {
         PyErr_Format(PyExc_KeyError, "getgrgid(): gid not found: %d", gid);
         return NULL;
     }
diff -r 59a2807872d5 Modules/parsermodule.c
--- a/Modules/parsermodule.c    Fri Sep 21 17:29:20 2012 +0300
+++ b/Modules/parsermodule.c    Fri Sep 21 19:21:25 2012 +0300
@@ -725,7 +725,7 @@
         /* elem must always be a sequence, however simple */
         PyObject* elem = PySequence_GetItem(tuple, i);
         int ok = elem != NULL;
-        long  type = 0;
+        int type = 0;
         char *strn = 0;
 
         if (ok)
@@ -736,8 +736,14 @@
                 ok = 0;
             else {
                 ok = PyLong_Check(temp);
-                if (ok)
-                    type = PyLong_AS_LONG(temp);
+                if (ok) {
+                    type = _PyLong_AsInt(temp);
+                    if (type == -1 && PyErr_Occurred()) {
+                        Py_DECREF(temp);
+                        Py_DECREF(elem);
+                        return 0;
+                    }
+                }
                 Py_DECREF(temp);
             }
         }
@@ -773,8 +779,16 @@
             if (len == 3) {
                 PyObject *o = PySequence_GetItem(elem, 2);
                 if (o != NULL) {
-                    if (PyLong_Check(o))
-                        *line_num = PyLong_AS_LONG(o);
+                    if (PyLong_Check(o)) {
+                        int num = _PyLong_AsInt(o);
+                        if (num == -1 && PyErr_Occurred()) {
+                            Py_DECREF(o);
+                            Py_DECREF(temp);
+                            Py_DECREF(elem);
+                            return 0;
+                        }
+                        *line_num = num;
+                    }
                     else {
                         PyErr_Format(parser_error,
                                      "third item in terminal node must be an"
diff -r 59a2807872d5 Modules/posixmodule.c
--- a/Modules/posixmodule.c     Fri Sep 21 17:29:20 2012 +0300
+++ b/Modules/posixmodule.c     Fri Sep 21 19:21:25 2012 +0300
@@ -8170,7 +8170,7 @@
     int fds[2];
     int res;
 
-    flags = PyLong_AsLong(arg);
+    flags = _PyLong_AsInt(arg);
     if (flags == -1 && PyErr_Occurred())
         return NULL;
 
@@ -9016,7 +9016,7 @@
  */
 struct constdef {
     char *name;
-    long value;
+    int value;
 };
 
 static int
@@ -9024,7 +9024,10 @@
               size_t tablesize)
 {
     if (PyLong_Check(arg)) {
-        *valuep = PyLong_AS_LONG(arg);
+        int value = _PyLong_AsInt(arg);
+        if (value == -1 && PyErr_Occurred())
+            return 0;
+        *valuep = value;
         return 1;
     }
     else {
diff -r 59a2807872d5 Modules/pyexpat.c
--- a/Modules/pyexpat.c Fri Sep 21 17:29:20 2012 +0300
+++ b/Modules/pyexpat.c Fri Sep 21 19:21:25 2012 +0300
@@ -1447,13 +1447,13 @@
     }
 
     if (PyUnicode_CompareWithASCIIString(name, "buffer_size") == 0) {
-      long new_buffer_size;
+      int new_buffer_size;
       if (!PyLong_Check(v)) {
         PyErr_SetString(PyExc_TypeError, "buffer_size must be an integer");
         return -1;
       }
 
-      new_buffer_size=PyLong_AS_LONG(v);
+      new_buffer_size = _PyLong_AsInt(v);
       /* trivial case -- no change */
       if (new_buffer_size == self->buffer_size) {
         return 0;
@@ -1464,14 +1464,6 @@
         return -1;
       }
 
-      /* check maximum */
-      if (new_buffer_size > INT_MAX) {
-        char errmsg[100];
-        sprintf(errmsg, "buffer_size must not be greater than %i", INT_MAX);
-        PyErr_SetString(PyExc_ValueError, errmsg);
-        return -1;
-      }
-
       if (self->buffer != NULL) {
         /* there is already a buffer */
         if (self->buffer_used != 0) {
diff -r 59a2807872d5 Modules/readline.c
--- a/Modules/readline.c        Fri Sep 21 17:29:20 2012 +0300
+++ b/Modules/readline.c        Fri Sep 21 19:21:25 2012 +0300
@@ -741,7 +741,7 @@
         if (r == Py_None)
             result = 0;
         else {
-            result = PyLong_AsLong(r);
+            result = _PyLong_AsInt(r);
             if (result == -1 && PyErr_Occurred())
                 goto error;
         }
diff -r 59a2807872d5 Modules/selectmodule.c
--- a/Modules/selectmodule.c    Fri Sep 21 17:29:20 2012 +0300
+++ b/Modules/selectmodule.c    Fri Sep 21 19:21:25 2012 +0300
@@ -359,10 +359,13 @@
 
     i = pos = 0;
     while (PyDict_Next(self->dict, &pos, &key, &value)) {
-        self->ufds[i].fd = PyLong_AsLong(key);
+        assert(i < self->ufd_len);
+        /* Never overflow */
+        self->ufds[i].fd = (int)PyLong_AsLong(key);
         self->ufds[i].events = (short)PyLong_AsLong(value);
         i++;
     }
+    assert(i == self->ufd_len);
     self->ufd_uptodate = 1;
     return 1;
 }
@@ -378,10 +381,11 @@
 poll_register(pollObject *self, PyObject *args)
 {
     PyObject *o, *key, *value;
-    int fd, events = POLLIN | POLLPRI | POLLOUT;
+    int fd;
+    short events = POLLIN | POLLPRI | POLLOUT;
     int err;
 
-    if (!PyArg_ParseTuple(args, "O|i:register", &o, &events)) {
+    if (!PyArg_ParseTuple(args, "O|h:register", &o, &events)) {
         return NULL;
     }
 
@@ -520,7 +524,7 @@
         tout = PyNumber_Long(tout);
         if (!tout)
             return NULL;
-        timeout = PyLong_AsLong(tout);
+        timeout = _PyLong_AsInt(tout);
         Py_DECREF(tout);
         if (timeout == -1 && PyErr_Occurred())
             return NULL;
@@ -804,7 +808,7 @@
     struct dvpoll dvp;
     PyObject *result_list = NULL, *tout = NULL;
     int poll_result, i;
-    long timeout;
+    int timeout;
     PyObject *value, *num1, *num2;
 
     if (!PyArg_UnpackTuple(args, "poll", 0, 1, &tout)) {
@@ -823,16 +827,15 @@
         tout = PyNumber_Long(tout);
         if (!tout)
             return NULL;
-        timeout = PyLong_AsLong(tout);
+        timeout = _PyLong_AsInt(tout);
         Py_DECREF(tout);
         if (timeout == -1 && PyErr_Occurred())
             return NULL;
-    }
-
-    if ((timeout < -1) || (timeout > INT_MAX)) {
-        PyErr_SetString(PyExc_OverflowError,
+        if (timeout < -1) {
+            PyErr_SetString(PyExc_OverflowError,
                         "timeout is out of range");
-        return NULL;
+            return NULL;
+        }
     }
 
     if (devpoll_flush(self))
diff -r 59a2807872d5 Modules/socketmodule.c
--- a/Modules/socketmodule.c    Fri Sep 21 17:29:20 2012 +0300
+++ b/Modules/socketmodule.c    Fri Sep 21 19:21:25 2012 +0300
@@ -2075,8 +2075,8 @@
 {
     int block;
 
-    block = PyLong_AsLong(arg);
-    if (block == -1 && PyErr_Occurred())
+    block = PyObject_IsTrue(arg);
+    if (block < 0)
         return NULL;
 
     s->sock_timeout = block ? -1.0 : 0.0;
@@ -2555,7 +2555,7 @@
     int backlog;
     int res;
 
-    backlog = PyLong_AsLong(arg);
+    backlog = _PyLong_AsInt(arg);
     if (backlog == -1 && PyErr_Occurred())
         return NULL;
     Py_BEGIN_ALLOW_THREADS
@@ -3712,7 +3712,7 @@
     int how;
     int res;
 
-    how = PyLong_AsLong(arg);
+    how = _PyLong_AsInt(arg);
     if (how == -1 && PyErr_Occurred())
         return NULL;
     Py_BEGIN_ALLOW_THREADS
diff -r 59a2807872d5 Objects/fileobject.c
--- a/Objects/fileobject.c      Fri Sep 21 17:29:20 2012 +0300
+++ b/Objects/fileobject.c      Fri Sep 21 19:21:25 2012 +0300
@@ -200,7 +200,7 @@
     _Py_IDENTIFIER(fileno);
 
     if (PyLong_Check(o)) {
-        fd = PyLong_AsLong(o);
+        fd = _PyLong_AsInt(o);
     }
     else if ((meth = _PyObject_GetAttrId(o, &PyId_fileno)) != NULL)
     {
@@ -210,7 +210,7 @@
             return -1;
 
         if (PyLong_Check(fno)) {
-            fd = PyLong_AsLong(fno);
+            fd = _PyLong_AsInt(fno);
             Py_DECREF(fno);
         }
         else {
diff -r 59a2807872d5 Objects/longobject.c
--- a/Objects/longobject.c      Fri Sep 21 17:29:20 2012 +0300
+++ b/Objects/longobject.c      Fri Sep 21 19:21:25 2012 +0300
@@ -434,6 +434,23 @@
     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 (int)result;
+}
+
 /* Get a Py_ssize_t from a long int object.
    Returns -1 and sets an error condition if overflow occurs. */
 
diff -r 59a2807872d5 Objects/structseq.c
--- a/Objects/structseq.c       Fri Sep 21 17:29:20 2012 +0300
+++ b/Objects/structseq.c       Fri Sep 21 19:21:25 2012 +0300
@@ -13,14 +13,14 @@
 char *PyStructSequence_UnnamedField = "unnamed field";
 
 #define VISIBLE_SIZE(op) Py_SIZE(op)
-#define VISIBLE_SIZE_TP(tp) PyLong_AsLong( \
+#define VISIBLE_SIZE_TP(tp) PyLong_AsSsize_t( \
                       PyDict_GetItemString((tp)->tp_dict, visible_length_key))
 
-#define REAL_SIZE_TP(tp) PyLong_AsLong( \
+#define REAL_SIZE_TP(tp) PyLong_AsSsize_t( \
                       PyDict_GetItemString((tp)->tp_dict, real_length_key))
 #define REAL_SIZE(op) REAL_SIZE_TP(Py_TYPE(op))
 
-#define UNNAMED_FIELDS_TP(tp) PyLong_AsLong( \
+#define UNNAMED_FIELDS_TP(tp) PyLong_AsSsize_t( \
                       PyDict_GetItemString((tp)->tp_dict, unnamed_fields_key))
 #define UNNAMED_FIELDS(op) UNNAMED_FIELDS_TP(Py_TYPE(op))
 
@@ -161,7 +161,8 @@
 #define TYPE_MAXSIZE 100
 
     PyTypeObject *typ = Py_TYPE(obj);
-    int i, removelast = 0;
+    Py_ssize_t i;
+    int removelast = 0;
     Py_ssize_t len;
     char buf[REPR_BUFFER_SIZE];
     char *endofbuf, *pbuf = buf;
@@ -233,8 +234,7 @@
     PyObject* tup;
     PyObject* dict;
     PyObject* result;
-    Py_ssize_t n_fields, n_visible_fields, n_unnamed_fields;
-    int i;
+    Py_ssize_t n_fields, n_visible_fields, n_unnamed_fields, i;
 
     n_fields = REAL_SIZE(self);
     n_visible_fields = VISIBLE_SIZE(self);
@@ -320,7 +320,7 @@
 {
     PyObject *dict;
     PyMemberDef* members;
-    int n_members, n_unnamed_members, i, k;
+    Py_ssize_t n_members, n_unnamed_members, i, k;
 
 #ifdef Py_TRACE_REFS
     /* if the type object was chained, unchain it first
@@ -365,18 +365,18 @@
     Py_INCREF(type);
 
     dict = type->tp_dict;
-#define SET_DICT_FROM_INT(key, value)                           \
+#define SET_DICT_FROM_SIZE(key, value)                          \
     do {                                                        \
-        PyObject *v = PyLong_FromLong((long) value);            \
+        PyObject *v = PyLong_FromSsize_t(value);                \
         if (v != NULL) {                                        \
             PyDict_SetItemString(dict, key, v);                 \
             Py_DECREF(v);                                       \
         }                                                       \
     } while (0)
 
-    SET_DICT_FROM_INT(visible_length_key, desc->n_in_sequence);
-    SET_DICT_FROM_INT(real_length_key, n_members);
-    SET_DICT_FROM_INT(unnamed_fields_key, n_unnamed_members);
+    SET_DICT_FROM_SIZE(visible_length_key, desc->n_in_sequence);
+    SET_DICT_FROM_SIZE(real_length_key, n_members);
+    SET_DICT_FROM_SIZE(unnamed_fields_key, n_unnamed_members);
 }
 
 PyTypeObject*
diff -r 59a2807872d5 Objects/unicodeobject.c
--- a/Objects/unicodeobject.c   Fri Sep 21 17:29:20 2012 +0300
+++ b/Objects/unicodeobject.c   Fri Sep 21 19:21:25 2012 +0300
@@ -13567,7 +13567,7 @@
                                     "* wants int");
                     goto onError;
                 }
-                width = PyLong_AsLong(v);
+                width = PyLong_AsSsize_t(v);
                 if (width == -1 && PyErr_Occurred())
                     goto onError;
                 if (width < 0) {
@@ -13607,7 +13607,7 @@
                                         "* wants int");
                         goto onError;
                     }
-                    prec = PyLong_AsLong(v);
+                    prec = _PyLong_AsInt(v);
                     if (prec == -1 && PyErr_Occurred())
                         goto onError;
                     if (prec < 0)
diff -r 59a2807872d5 Python/Python-ast.c
--- a/Python/Python-ast.c       Fri Sep 21 17:29:20 2012 +0300
+++ b/Python/Python-ast.c       Fri Sep 21 19:21:25 2012 +0300
@@ -730,7 +730,7 @@
         return 1;
     }
 
-    i = (int)PyLong_AsLong(obj);
+    i = _PyLong_AsInt(obj);
     if (i == -1 && PyErr_Occurred())
         return 1;
     *out = i;
diff -r 59a2807872d5 Python/compile.c
--- a/Python/compile.c  Fri Sep 21 17:29:20 2012 +0300
+++ b/Python/compile.c  Fri Sep 21 19:21:25 2012 +0300
@@ -426,6 +426,7 @@
         v = PyDict_GetItem(src, k);
         assert(PyLong_Check(v));
         vi = PyLong_AS_LONG(v);
+        assert(!PyErr_Occurred());
         scope = (vi >> SCOPE_OFFSET) & SCOPE_MASK;
 
         if (scope == scope_type || vi & flag) {
@@ -1065,7 +1066,7 @@
         Py_DECREF(v);
     }
     else
-        arg = PyLong_AsLong(v);
+        arg = PyLong_AsSsize_t(v);
     Py_DECREF(t);
     return arg;
 }
diff -r 59a2807872d5 Python/pythonrun.c
--- a/Python/pythonrun.c        Fri Sep 21 17:29:20 2012 +0300
+++ b/Python/pythonrun.c        Fri Sep 21 19:21:25 2012 +0300
@@ -1478,7 +1478,7 @@
 parse_syntax_error(PyObject *err, PyObject **message, const char **filename,
                    int *lineno, int *offset, const char **text)
 {
-    long hold;
+    int hold;
     PyObject *v;
     _Py_IDENTIFIER(msg);
     _Py_IDENTIFIER(filename);
@@ -1510,11 +1510,11 @@
     v = _PyObject_GetAttrId(err, &PyId_lineno);
     if (!v)
         goto finally;
-    hold = PyLong_AsLong(v);
+    hold = _PyLong_AsInt(v);
     Py_DECREF(v);
     if (hold < 0 && PyErr_Occurred())
         goto finally;
-    *lineno = (int)hold;
+    *lineno = hold;
 
     v = _PyObject_GetAttrId(err, &PyId_offset);
     if (!v)
@@ -1523,11 +1523,11 @@
         *offset = -1;
         Py_DECREF(v);
     } else {
-        hold = PyLong_AsLong(v);
+        hold = _PyLong_AsInt(v);
         Py_DECREF(v);
         if (hold < 0 && PyErr_Occurred())
             goto finally;
-        *offset = (int)hold;
+        *offset = hold;
     }
 
     v = _PyObject_GetAttrId(err, &PyId_text);
@@ -1616,7 +1616,7 @@
            just let the else clause below print the error. */
     }
     if (PyLong_Check(value))
-        exitcode = (int)PyLong_AsLong(value);
+        exitcode = _PyLong_AsInt(value);
     else {
         PyObject *sys_stderr = PySys_GetObject("stderr");
         if (sys_stderr != NULL && sys_stderr != Py_None) {
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to