Skip to content
This repository was archived by the owner on Feb 13, 2025. It is now read-only.

Commit 99bb14b

Browse files
committed
type_call() now detect bugs in type new and init
* Call _Py_CheckFunctionResult() to check for bugs in type constructors (tp_new) * Add assertions to ensure an exception was raised if tp_init failed or that no exception was raised if tp_init succeed Refactor also the function to have less indentation.
1 parent 31eb5fb commit 99bb14b

File tree

1 file changed

+27
-19
lines changed

1 file changed

+27
-19
lines changed

Objects/typeobject.c

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -906,25 +906,33 @@ type_call(PyTypeObject *type, PyObject *args, PyObject *kwds)
906906
#endif
907907

908908
obj = type->tp_new(type, args, kwds);
909-
if (obj != NULL) {
910-
/* Ugly exception: when the call was type(something),
911-
don't call tp_init on the result. */
912-
if (type == &PyType_Type &&
913-
PyTuple_Check(args) && PyTuple_GET_SIZE(args) == 1 &&
914-
(kwds == NULL ||
915-
(PyDict_Check(kwds) && PyDict_Size(kwds) == 0)))
916-
return obj;
917-
/* If the returned object is not an instance of type,
918-
it won't be initialized. */
919-
if (!PyType_IsSubtype(Py_TYPE(obj), type))
920-
return obj;
921-
type = Py_TYPE(obj);
922-
if (type->tp_init != NULL) {
923-
int res = type->tp_init(obj, args, kwds);
924-
if (res < 0) {
925-
Py_DECREF(obj);
926-
obj = NULL;
927-
}
909+
obj = _Py_CheckFunctionResult((PyObject*)type, obj, NULL);
910+
if (obj == NULL)
911+
return NULL;
912+
913+
/* Ugly exception: when the call was type(something),
914+
don't call tp_init on the result. */
915+
if (type == &PyType_Type &&
916+
PyTuple_Check(args) && PyTuple_GET_SIZE(args) == 1 &&
917+
(kwds == NULL ||
918+
(PyDict_Check(kwds) && PyDict_Size(kwds) == 0)))
919+
return obj;
920+
921+
/* If the returned object is not an instance of type,
922+
it won't be initialized. */
923+
if (!PyType_IsSubtype(Py_TYPE(obj), type))
924+
return obj;
925+
926+
type = Py_TYPE(obj);
927+
if (type->tp_init != NULL) {
928+
int res = type->tp_init(obj, args, kwds);
929+
if (res < 0) {
930+
assert(PyErr_Occurred());
931+
Py_DECREF(obj);
932+
obj = NULL;
933+
}
934+
else {
935+
assert(!PyErr_Occurred());
928936
}
929937
}
930938
return obj;

0 commit comments

Comments
 (0)