]> granicus.if.org Git - python/commitdiff
Issue 2440: fix the handling of %n in Python/getargs.c's convertsimple(), extend...
authorTrent Nelson <trent.nelson@snakebite.org>
Thu, 10 Apr 2008 16:25:37 +0000 (16:25 +0000)
committerTrent Nelson <trent.nelson@snakebite.org>
Thu, 10 Apr 2008 16:25:37 +0000 (16:25 +0000)
Lib/test/test_getargs2.py
Objects/abstract.c
Python/getargs.c

index 19183867f9da5bed081f467b3e3668cddd9c810b..d8f63092398b812946e2290c053ce46e3a3a3cd0 100644 (file)
@@ -63,6 +63,10 @@ class Int:
     def __int__(self):
         return 99
 
+class InvalidLongAsString:
+    def __int__(self):
+        return 'foobar'
+
 class Unsigned_TestCase(unittest.TestCase):
     def test_b(self):
         from _testcapi import getargs_b
@@ -199,6 +203,7 @@ class Signed_TestCase(unittest.TestCase):
         self.failUnlessEqual(42, getargs_n(42))
         self.assertRaises(OverflowError, getargs_n, VERY_LARGE)
 
+        self.assertRaises(TypeError, getargs_n, InvalidLongAsString())
 
 class LongLong_TestCase(unittest.TestCase):
     def test_L(self):
index dac80d92fa0de729edde970fc0977041b3a76571..6335aa2cae9c25da7d4c226a4424b8e717ddb255 100644 (file)
@@ -1220,6 +1220,7 @@ PyNumber_Absolute(PyObject *o)
 PyObject *
 PyNumber_Index(PyObject *item)
 {
+       PyNumberMethods *m;
        PyObject *result = NULL;
        if (item == NULL)
                return null_error();
@@ -1227,8 +1228,9 @@ PyNumber_Index(PyObject *item)
                Py_INCREF(item);
                return item;
        }
+       m = item->ob_type->tp_as_number;
        if (PyIndex_Check(item)) {
-               result = item->ob_type->tp_as_number->nb_index(item);
+               result = m->nb_index(item);
                if (result && !PyLong_Check(result)) {
                        PyErr_Format(PyExc_TypeError,
                                     "__index__ returned non-int "
@@ -1238,7 +1240,17 @@ PyNumber_Index(PyObject *item)
                        return NULL;
                }
        }
-       else {
+       else if (m && m->nb_int != NULL) {
+               result = m->nb_int(item);
+               if (result && !PyLong_Check(result)) {
+                       PyErr_Format(PyExc_TypeError,
+                                    "__int__ returned non-int "
+                                    "(type %.200s)",
+                                    result->ob_type->tp_name);
+                       Py_DECREF(result);
+                       return NULL;
+               }
+       } else {
                PyErr_Format(PyExc_TypeError,
                             "'%.200s' object cannot be interpreted "
                             "as an integer", item->ob_type->tp_name);
index 1370e098adcd44908f55a70916e448998b5a2827..960c68c93c8764270131e530e66cbcf519a6fe61 100644 (file)
@@ -663,7 +663,6 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
        }
 
        case 'n': /* Py_ssize_t */
-#if SIZEOF_SIZE_T != SIZEOF_LONG
        {
                PyObject *iobj;
                Py_ssize_t *p = va_arg(*p_va, Py_ssize_t *);
@@ -672,14 +671,13 @@ convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
                        return converterr("integer<n>", arg, msgbuf, bufsize);
                iobj = PyNumber_Index(arg);
                if (iobj != NULL)
-                       ival = PyLong_AsSsize_t(arg);
+                       ival = PyLong_AsSsize_t(iobj);
                if (ival == -1 && PyErr_Occurred())
                        return converterr("integer<n>", arg, msgbuf, bufsize);
                *p = ival;
                break;
        }
-#endif
-       /* Fall through from 'n' to 'l' if Py_ssize_t is int */
+
        case 'l': {/* long int */
                long *p = va_arg(*p_va, long *);
                long ival;