Skip to content

Commit 60324d2

Browse files
bpo-42143: Ensure PyFunction_NewWithQualName() can't fail after creating the func object (GH-22953) (GH-23021)
func_dealloc() does not handle partially-created objects. Best not to give it any. (cherry picked from commit 3505261) Co-authored-by: Yonatan Goldschmidt <[email protected]>
1 parent 577d7c4 commit 60324d2

File tree

2 files changed

+18
-13
lines changed

2 files changed

+18
-13
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix handling of errors during creation of ``PyFunctionObject``, which resulted
2+
in operations on uninitialized memory. Patch by Yonatan Goldschmidt.

Objects/funcobject.c

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,23 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname
2020
return NULL;
2121
}
2222

23+
/* __module__: If module name is in globals, use it.
24+
Otherwise, use None. */
25+
module = PyDict_GetItemWithError(globals, __name__);
26+
if (module) {
27+
Py_INCREF(module);
28+
}
29+
else if (PyErr_Occurred()) {
30+
return NULL;
31+
}
32+
2333
op = PyObject_GC_New(PyFunctionObject, &PyFunction_Type);
24-
if (op == NULL)
34+
if (op == NULL) {
35+
Py_XDECREF(module);
2536
return NULL;
37+
}
38+
/* Note: No failures from this point on, since func_dealloc() does not
39+
expect a partially-created object. */
2640

2741
op->func_weakreflist = NULL;
2842
Py_INCREF(code);
@@ -35,6 +49,7 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname
3549
op->func_kwdefaults = NULL; /* No keyword only defaults */
3650
op->func_closure = NULL;
3751
op->vectorcall = _PyFunction_Vectorcall;
52+
op->func_module = module;
3853

3954
consts = ((PyCodeObject *)code)->co_consts;
4055
if (PyTuple_Size(consts) >= 1) {
@@ -48,20 +63,8 @@ PyFunction_NewWithQualName(PyObject *code, PyObject *globals, PyObject *qualname
4863
op->func_doc = doc;
4964

5065
op->func_dict = NULL;
51-
op->func_module = NULL;
5266
op->func_annotations = NULL;
5367

54-
/* __module__: If module name is in globals, use it.
55-
Otherwise, use None. */
56-
module = PyDict_GetItemWithError(globals, __name__);
57-
if (module) {
58-
Py_INCREF(module);
59-
op->func_module = module;
60-
}
61-
else if (PyErr_Occurred()) {
62-
Py_DECREF(op);
63-
return NULL;
64-
}
6568
if (qualname)
6669
op->func_qualname = qualname;
6770
else

0 commit comments

Comments
 (0)