summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Dickinson <mdickinson@enthought.com>2012-09-27 18:38:59 (GMT)
committerMark Dickinson <mdickinson@enthought.com>2012-09-27 18:38:59 (GMT)
commit7c95bb35e40a1bb598a259248b5a9880d8716556 (patch)
tree5891ec02508da616ea5bc98e31ac75d9c26663e4
parent3658cb3012fa14e4594ed62a227115fbbd15da26 (diff)
downloadcpython-7c95bb35e40a1bb598a259248b5a9880d8716556.zip
cpython-7c95bb35e40a1bb598a259248b5a9880d8716556.tar.gz
cpython-7c95bb35e40a1bb598a259248b5a9880d8716556.tar.bz2
Issue #16060: Fix a double DECREF in int() implementation. Thanks Serhiy Storchaka.
-rw-r--r--Lib/test/test_int.py12
-rw-r--r--Misc/NEWS3
-rw-r--r--Objects/abstract.c7
3 files changed, 18 insertions, 4 deletions
diff --git a/Lib/test/test_int.py b/Lib/test/test_int.py
index 437e323..227759f 100644
--- a/Lib/test/test_int.py
+++ b/Lib/test/test_int.py
@@ -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:
diff --git a/Misc/NEWS b/Misc/NEWS
index b1e59b8..c0e6508 100644
--- 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
diff --git a/Objects/abstract.c b/Objects/abstract.c
index ed5e196..a2737dd 100644
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -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);