Skip to content

Commit a444686

Browse files
committed
bpo-33930: Fix segfault with deep recursion when cleaning method objects
1 parent f5cbea6 commit a444686

File tree

3 files changed

+15
-1
lines changed

3 files changed

+15
-1
lines changed

Lib/test/test_exceptions.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,6 +1027,16 @@ def g():
10271027
self.assertIsInstance(v, RecursionError, type(v))
10281028
self.assertIn("maximum recursion depth exceeded", str(v))
10291029

1030+
1031+
@cpython_only
1032+
def test_crashcan_recursion(self):
1033+
def foo():
1034+
o = object()
1035+
for x in range(1000000):
1036+
o = o.__dir__
1037+
1038+
foo()
1039+
10301040
@cpython_only
10311041
def test_recursion_normalizing_exception(self):
10321042
# Issue #22898.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix segmentation failt with deep recursion when cleaning method objects.
2+
Patch by Augusto Goulart and Pablo Galindo.

Objects/methodobject.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,8 @@ PyCMethod_GetClass(PyObject *op)
160160
static void
161161
meth_dealloc(PyCFunctionObject *m)
162162
{
163-
_PyObject_GC_UNTRACK(m);
163+
PyObject_GC_UnTrack(m);
164+
Py_TRASHCAN_SAFE_BEGIN(m);
164165
if (m->m_weakreflist != NULL) {
165166
PyObject_ClearWeakRefs((PyObject*) m);
166167
}
@@ -170,6 +171,7 @@ meth_dealloc(PyCFunctionObject *m)
170171
Py_XDECREF(m->m_self);
171172
Py_XDECREF(m->m_module);
172173
PyObject_GC_Del(m);
174+
Py_TRASHCAN_SAFE_END(m);
173175
}
174176

175177
static PyObject *

0 commit comments

Comments
 (0)