mirror of
https://github.com/AdaCore/cpython.git
synced 2026-02-12 12:57:15 -08:00
bpo-41909: Enable previously disabled recursion checks. (GH-22536)
Enable recursion checks which were disabled when get __bases__ of non-type objects in issubclass() and isinstance() and when intern strings. It fixes a stack overflow when getting __bases__ leads to infinite recursion. Originally recursion checks was disabled for PyDict_GetItem() which silences all errors including the one raised in case of detected recursion and can return incorrect result. But now the code uses PyDict_GetItemWithError() and PyDict_SetDefault() instead.
This commit is contained in:
@@ -303,6 +303,16 @@ class TestIsInstanceIsSubclass(unittest.TestCase):
|
||||
|
||||
self.assertEqual(True, issubclass(B(), int))
|
||||
|
||||
def test_infinite_recursion_in_bases(self):
|
||||
class X:
|
||||
@property
|
||||
def __bases__(self):
|
||||
return self.__bases__
|
||||
|
||||
self.assertRaises(RecursionError, issubclass, X(), int)
|
||||
self.assertRaises(RecursionError, issubclass, int, X())
|
||||
self.assertRaises(RecursionError, isinstance, 1, X())
|
||||
|
||||
|
||||
def blowstack(fxn, arg, compare_to):
|
||||
# Make sure that calling isinstance with a deeply nested tuple for its
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
Fixed stack overflow in :func:`issubclass` and :func:`isinstance` when
|
||||
getting the ``__bases__`` attribute leads to infinite recursion.
|
||||
@@ -2336,9 +2336,7 @@ abstract_get_bases(PyObject *cls)
|
||||
_Py_IDENTIFIER(__bases__);
|
||||
PyObject *bases;
|
||||
|
||||
Py_ALLOW_RECURSION
|
||||
(void)_PyObject_LookupAttrId(cls, &PyId___bases__, &bases);
|
||||
Py_END_ALLOW_RECURSION
|
||||
if (bases != NULL && !PyTuple_Check(bases)) {
|
||||
Py_DECREF(bases);
|
||||
return NULL;
|
||||
|
||||
@@ -15734,9 +15734,7 @@ PyUnicode_InternInPlace(PyObject **p)
|
||||
}
|
||||
|
||||
PyObject *t;
|
||||
Py_ALLOW_RECURSION
|
||||
t = PyDict_SetDefault(interned, s, s);
|
||||
Py_END_ALLOW_RECURSION
|
||||
|
||||
if (t == NULL) {
|
||||
PyErr_Clear();
|
||||
|
||||
Reference in New Issue
Block a user