]> granicus.if.org Git - python/commitdiff
Issue #16060: Fix a double DECREF in int() implementation. Thanks Serhiy Storchaka.
authorMark Dickinson <mdickinson@enthought.com>
Thu, 27 Sep 2012 18:38:59 +0000 (19:38 +0100)
committerMark Dickinson <mdickinson@enthought.com>
Thu, 27 Sep 2012 18:38:59 +0000 (19:38 +0100)
Lib/test/test_int.py
Misc/NEWS
Objects/abstract.c

index 437e323cbccf8d0ddbe27fc3df6e8e3edd83aa6b..227759f2696a2dd67fe4a13e5dff9c9170d2ef38 100644 (file)
@@ -305,6 +305,18 @@ class IntTestCases(unittest.TestCase):
                     self.fail("Failed to raise TypeError with %s" %
                               ((base, trunc_result_base),))
 
+                # Regression test for bugs.python.org/issue16060.
+                class BadInt(trunc_result_base):
+                    def __int__(self):
+                        return 42.0
+
+                class TruncReturnsBadInt(base):
+                    def __trunc__(self):
+                        return BadInt()
+
+                with self.assertRaises(TypeError):
+                    int(TruncReturnsBadInt())
+
     def test_error_message(self):
         testlist = ('\xbd', '123\xbd', '  123 456  ')
         for s in testlist:
index b1e59b841afa2a7b4a823bd15ed03e7c726e9548..c0e6508d214689fec6854a4de14fa33cb40e0911 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,9 @@ What's New in Python 3.3.1?
 Core and Builtins
 -----------------
 
+- Issue #16060: Fix refcounting bug when __trunc__ returns an object
+  whose __int__ gives a non-integer.  Patch by Serhiy Storchaka.
+
 - Issue #16046: Fix loading sourceless legacy pyos.
 
 - Issue #15379: Fix passing of non-BMP characters as integers for the charmap
index ed5e196843c09e0e13b3b3652fdb1539b1de815e..a2737dd5f4fb2910213cb822df770cc21779b376 100644 (file)
@@ -1228,11 +1228,10 @@ convert_integral_to_int(PyObject *integral, const char *error_format)
     nb = Py_TYPE(integral)->tp_as_number;
     if (nb->nb_int) {
         PyObject *as_int = nb->nb_int(integral);
-        Py_DECREF(integral);
-        if (!as_int)
-            return NULL;
-        if (PyLong_Check(as_int))
+        if (!as_int || PyLong_Check(as_int)) {
+            Py_DECREF(integral);
             return as_int;
+        }
         Py_DECREF(as_int);
     }
     PyErr_Format(PyExc_TypeError, error_format, Py_TYPE(integral)->tp_name);