bpo-44856: Possible reference leak in error paths of update_bases() a… · python/cpython@ed718e9
@@ -71,6 +71,7 @@ update_bases(PyObject *bases, PyObject *const *args, Py_ssize_t nargs)
7171/* If this is a first successful replacement, create new_bases list and
7272 copy previously encountered bases. */
7373if (!(new_bases = PyList_New(i))) {
74+Py_DECREF(new_base);
7475 goto error;
7576 }
7677for (j = 0; j < i; j++) {
@@ -81,6 +82,7 @@ update_bases(PyObject *bases, PyObject *const *args, Py_ssize_t nargs)
8182 }
8283j = PyList_GET_SIZE(new_bases);
8384if (PyList_SetSlice(new_bases, j, j, new_base) < 0) {
85+Py_DECREF(new_base);
8486 goto error;
8587 }
8688Py_DECREF(new_base);
@@ -102,8 +104,9 @@ static PyObject *
102104builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs,
103105PyObject *kwnames)
104106{
105-PyObject *func, *name, *bases, *mkw, *meta, *winner, *prep, *ns, *orig_bases;
106-PyObject *cls = NULL, *cell = NULL;
107+PyObject *func, *name, *winner, *prep;
108+PyObject *cls = NULL, *cell = NULL, *ns = NULL, *meta = NULL, *orig_bases = NULL;
109+PyObject *mkw = NULL, *bases = NULL;
107110int isclass = 0; /* initialize to prevent gcc warning */
108111109112if (nargs < 2) {
@@ -140,26 +143,20 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs,
140143else {
141144mkw = _PyStack_AsDict(args + nargs, kwnames);
142145if (mkw == NULL) {
143-Py_DECREF(bases);
144-return NULL;
146+ goto error;
145147 }
146148147149meta = _PyDict_GetItemIdWithError(mkw, &PyId_metaclass);
148150if (meta != NULL) {
149151Py_INCREF(meta);
150152if (_PyDict_DelItemId(mkw, &PyId_metaclass) < 0) {
151-Py_DECREF(meta);
152-Py_DECREF(mkw);
153-Py_DECREF(bases);
154-return NULL;
153+ goto error;
155154 }
156155/* metaclass is explicitly given, check if it's indeed a class */
157156isclass = PyType_Check(meta);
158157 }
159158else if (PyErr_Occurred()) {
160-Py_DECREF(mkw);
161-Py_DECREF(bases);
162-return NULL;
159+ goto error;
163160 }
164161 }
165162if (meta == NULL) {
@@ -182,10 +179,7 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs,
182179winner = (PyObject *)_PyType_CalculateMetaclass((PyTypeObject *)meta,
183180bases);
184181if (winner == NULL) {
185-Py_DECREF(meta);
186-Py_XDECREF(mkw);
187-Py_DECREF(bases);
188-return NULL;
182+ goto error;
189183 }
190184if (winner != meta) {
191185Py_DECREF(meta);
@@ -207,10 +201,7 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs,
207201Py_DECREF(prep);
208202 }
209203if (ns == NULL) {
210-Py_DECREF(meta);
211-Py_XDECREF(mkw);
212-Py_DECREF(bases);
213-return NULL;
204+ goto error;
214205 }
215206if (!PyMapping_Check(ns)) {
216207PyErr_Format(PyExc_TypeError,
@@ -251,13 +242,13 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs,
251242 }
252243error:
253244Py_XDECREF(cell);
254-Py_DECREF(ns);
255-Py_DECREF(meta);
245+Py_XDECREF(ns);
246+Py_XDECREF(meta);
256247Py_XDECREF(mkw);
257-Py_DECREF(bases);
258248if (bases != orig_bases) {
259249Py_DECREF(orig_bases);
260250 }
251+Py_DECREF(bases);
261252return cls;
262253}
263254