Skip to content

Commit 28521e9

Browse files
committed
Add defensive NULL checks in mro resolution
Currently, there are a few places where tp_mro could theoretically become NULL, but do not in practice. We should defensively check for NULL values to ensure that any changes do not introduce a crash and that state invariants are upheld.
1 parent 96905bd commit 28521e9

File tree

1 file changed

+7
-1
lines changed

1 file changed

+7
-1
lines changed

Objects/typeobject.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1652,6 +1652,7 @@ mro_hierarchy(PyTypeObject *type, PyObject *temp)
16521652
return res;
16531653
}
16541654
PyObject *new_mro = lookup_tp_mro(type);
1655+
assert(new_mro != NULL);
16551656

16561657
PyObject *tuple;
16571658
if (old_mro != NULL) {
@@ -3274,6 +3275,7 @@ mro_implementation_unlocked(PyTypeObject *type)
32743275
*/
32753276
PyTypeObject *base = _PyType_CAST(PyTuple_GET_ITEM(bases, 0));
32763277
PyObject *base_mro = lookup_tp_mro(base);
3278+
assert(base_mro != NULL);
32773279
Py_ssize_t k = PyTuple_GET_SIZE(base_mro);
32783280
PyObject *result = PyTuple_New(k + 1);
32793281
if (result == NULL) {
@@ -3308,9 +3310,12 @@ mro_implementation_unlocked(PyTypeObject *type)
33083310
return NULL;
33093311
}
33103312

3313+
PyObject *mro_to_merge;
33113314
for (Py_ssize_t i = 0; i < n; i++) {
33123315
PyTypeObject *base = _PyType_CAST(PyTuple_GET_ITEM(bases, i));
3313-
to_merge[i] = lookup_tp_mro(base);
3316+
mro_to_merge = lookup_tp_mro(base);
3317+
assert(mro_to_merge != NULL);
3318+
to_merge[i] = mro_to_merge;
33143319
}
33153320
to_merge[n] = bases;
33163321

@@ -8598,6 +8603,7 @@ type_ready_inherit(PyTypeObject *type)
85988603

85998604
// Inherit slots
86008605
PyObject *mro = lookup_tp_mro(type);
8606+
assert(mro != NULL);
86018607
Py_ssize_t n = PyTuple_GET_SIZE(mro);
86028608
for (Py_ssize_t i = 1; i < n; i++) {
86038609
PyObject *b = PyTuple_GET_ITEM(mro, i);

0 commit comments

Comments
 (0)