Skip to content

Commit 9776890

Browse files
tiranmiss-islington
authored andcommitted
pythongh-96046: Initialize ht_cached_keys in PyType_Ready() (pythonGH-96047)
(cherry picked from commit 53e6a9a) Co-authored-by: Christian Heimes <[email protected]>
1 parent fedd25e commit 9776890

File tree

2 files changed

+30
-9
lines changed

2 files changed

+30
-9
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
:c:func:`PyType_Ready` now initializes ``ht_cached_keys`` and performs
2+
additional checks to ensure that type objects are properly configured. This
3+
avoids crashes in 3rd party packages that don't use regular API to create
4+
new types.

Objects/typeobject.c

+26-9
Original file line numberDiff line numberDiff line change
@@ -3202,11 +3202,6 @@ type_new_impl(type_new_ctx *ctx)
32023202
// Put the proper slots in place
32033203
fixup_slot_dispatchers(type);
32043204

3205-
if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) {
3206-
PyHeapTypeObject *et = (PyHeapTypeObject*)type;
3207-
et->ht_cached_keys = _PyDict_NewKeysForClass();
3208-
}
3209-
32103205
if (type_new_set_names(type) < 0) {
32113206
goto error;
32123207
}
@@ -3588,10 +3583,6 @@ PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases)
35883583
if (PyType_Ready(type) < 0)
35893584
goto fail;
35903585

3591-
if (type->tp_flags & Py_TPFLAGS_MANAGED_DICT) {
3592-
res->ht_cached_keys = _PyDict_NewKeysForClass();
3593-
}
3594-
35953586
if (type->tp_doc) {
35963587
PyObject *__doc__ = PyUnicode_FromString(_PyType_DocWithoutSignature(type->tp_name, type->tp_doc));
35973588
if (!__doc__)
@@ -6409,6 +6400,29 @@ type_ready_set_new(PyTypeObject *type)
64096400
return 0;
64106401
}
64116402

6403+
static int
6404+
type_ready_managed_dict(PyTypeObject *type)
6405+
{
6406+
if (!(type->tp_flags & Py_TPFLAGS_MANAGED_DICT)) {
6407+
return 0;
6408+
}
6409+
if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE)) {
6410+
PyErr_Format(PyExc_SystemError,
6411+
"type %s has the Py_TPFLAGS_MANAGED_DICT flag "
6412+
"but not Py_TPFLAGS_HEAPTYPE flag",
6413+
type->tp_name);
6414+
return -1;
6415+
}
6416+
PyHeapTypeObject* et = (PyHeapTypeObject*)type;
6417+
if (et->ht_cached_keys == NULL) {
6418+
et->ht_cached_keys = _PyDict_NewKeysForClass();
6419+
if (et->ht_cached_keys == NULL) {
6420+
PyErr_NoMemory();
6421+
return -1;
6422+
}
6423+
}
6424+
return 0;
6425+
}
64126426

64136427
static int
64146428
type_ready_post_checks(PyTypeObject *type)
@@ -6469,6 +6483,9 @@ type_ready(PyTypeObject *type)
64696483
if (type_ready_add_subclasses(type) < 0) {
64706484
return -1;
64716485
}
6486+
if (type_ready_managed_dict(type) < 0) {
6487+
return -1;
6488+
}
64726489
if (type_ready_post_checks(type) < 0) {
64736490
return -1;
64746491
}

0 commit comments

Comments
 (0)