diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-08-07-01-26-12.bpo-44856.9rk3li.rst b/Misc/NEWS.d/next/Core and Builtins/2021-08-07-01-26-12.bpo-44856.9rk3li.rst new file mode 100644 index 00000000000000..1111d01b726fa2 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2021-08-07-01-26-12.bpo-44856.9rk3li.rst @@ -0,0 +1 @@ +Fix reference leaks in the error paths of ``update_bases()`` and ``__build_class__``. Patch by Pablo Galindo. diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index 3767f552bb17aa..4c0129c5c8ae43 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -71,6 +71,7 @@ update_bases(PyObject *bases, PyObject *const *args, Py_ssize_t nargs) /* If this is a first successful replacement, create new_bases list and copy previously encountered bases. */ if (!(new_bases = PyList_New(i))) { + Py_DECREF(new_base); goto error; } for (j = 0; j < i; j++) { @@ -81,6 +82,7 @@ update_bases(PyObject *bases, PyObject *const *args, Py_ssize_t nargs) } j = PyList_GET_SIZE(new_bases); if (PyList_SetSlice(new_bases, j, j, new_base) < 0) { + Py_DECREF(new_base); goto error; } Py_DECREF(new_base); @@ -102,8 +104,9 @@ static PyObject * builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *func, *name, *bases, *mkw, *meta, *winner, *prep, *ns, *orig_bases; - PyObject *cls = NULL, *cell = NULL; + PyObject *func, *name, *winner, *prep; + PyObject *cls = NULL, *cell = NULL, *ns = NULL, *meta = NULL, *orig_bases = NULL; + PyObject *mkw = NULL, *bases = NULL; int isclass = 0; /* initialize to prevent gcc warning */ if (nargs < 2) { @@ -140,26 +143,20 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs, else { mkw = _PyStack_AsDict(args + nargs, kwnames); if (mkw == NULL) { - Py_DECREF(bases); - return NULL; + goto error; } meta = _PyDict_GetItemIdWithError(mkw, &PyId_metaclass); if (meta != NULL) { Py_INCREF(meta); if (_PyDict_DelItemId(mkw, &PyId_metaclass) < 0) { - Py_DECREF(meta); - Py_DECREF(mkw); - Py_DECREF(bases); - return NULL; + goto error; } /* metaclass is explicitly given, check if it's indeed a class */ isclass = PyType_Check(meta); } else if (PyErr_Occurred()) { - Py_DECREF(mkw); - Py_DECREF(bases); - return NULL; + goto error; } } if (meta == NULL) { @@ -182,10 +179,7 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs, winner = (PyObject *)_PyType_CalculateMetaclass((PyTypeObject *)meta, bases); if (winner == NULL) { - Py_DECREF(meta); - Py_XDECREF(mkw); - Py_DECREF(bases); - return NULL; + goto error; } if (winner != meta) { Py_DECREF(meta); @@ -207,10 +201,7 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs, Py_DECREF(prep); } if (ns == NULL) { - Py_DECREF(meta); - Py_XDECREF(mkw); - Py_DECREF(bases); - return NULL; + goto error; } if (!PyMapping_Check(ns)) { PyErr_Format(PyExc_TypeError, @@ -251,13 +242,13 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs, } error: Py_XDECREF(cell); - Py_DECREF(ns); - Py_DECREF(meta); + Py_XDECREF(ns); + Py_XDECREF(meta); Py_XDECREF(mkw); - Py_DECREF(bases); if (bases != orig_bases) { Py_DECREF(orig_bases); } + Py_DECREF(bases); return cls; }