Skip to content

Commit a40675c

Browse files
authored
bpo-44856: Possible reference leak in error paths of update_bases() and __build_class__ (GH-27647)
1 parent 17c2316 commit a40675c

File tree

2 files changed

+14
-22
lines changed

2 files changed

+14
-22
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix reference leaks in the error paths of ``update_bases()`` and ``__build_class__``. Patch by Pablo Galindo.

Python/bltinmodule.c

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ update_bases(PyObject *bases, PyObject *const *args, Py_ssize_t nargs)
7272
/* If this is a first successful replacement, create new_bases list and
7373
copy previously encountered bases. */
7474
if (!(new_bases = PyList_New(i))) {
75+
Py_DECREF(new_base);
7576
goto error;
7677
}
7778
for (j = 0; j < i; j++) {
@@ -82,6 +83,7 @@ update_bases(PyObject *bases, PyObject *const *args, Py_ssize_t nargs)
8283
}
8384
j = PyList_GET_SIZE(new_bases);
8485
if (PyList_SetSlice(new_bases, j, j, new_base) < 0) {
86+
Py_DECREF(new_base);
8587
goto error;
8688
}
8789
Py_DECREF(new_base);
@@ -103,8 +105,9 @@ static PyObject *
103105
builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs,
104106
PyObject *kwnames)
105107
{
106-
PyObject *func, *name, *bases, *mkw, *meta, *winner, *prep, *ns, *orig_bases;
107-
PyObject *cls = NULL, *cell = NULL;
108+
PyObject *func, *name, *winner, *prep;
109+
PyObject *cls = NULL, *cell = NULL, *ns = NULL, *meta = NULL, *orig_bases = NULL;
110+
PyObject *mkw = NULL, *bases = NULL;
108111
int isclass = 0; /* initialize to prevent gcc warning */
109112

110113
if (nargs < 2) {
@@ -141,26 +144,20 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs,
141144
else {
142145
mkw = _PyStack_AsDict(args + nargs, kwnames);
143146
if (mkw == NULL) {
144-
Py_DECREF(bases);
145-
return NULL;
147+
goto error;
146148
}
147149

148150
meta = _PyDict_GetItemIdWithError(mkw, &PyId_metaclass);
149151
if (meta != NULL) {
150152
Py_INCREF(meta);
151153
if (_PyDict_DelItemId(mkw, &PyId_metaclass) < 0) {
152-
Py_DECREF(meta);
153-
Py_DECREF(mkw);
154-
Py_DECREF(bases);
155-
return NULL;
154+
goto error;
156155
}
157156
/* metaclass is explicitly given, check if it's indeed a class */
158157
isclass = PyType_Check(meta);
159158
}
160159
else if (PyErr_Occurred()) {
161-
Py_DECREF(mkw);
162-
Py_DECREF(bases);
163-
return NULL;
160+
goto error;
164161
}
165162
}
166163
if (meta == NULL) {
@@ -183,10 +180,7 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs,
183180
winner = (PyObject *)_PyType_CalculateMetaclass((PyTypeObject *)meta,
184181
bases);
185182
if (winner == NULL) {
186-
Py_DECREF(meta);
187-
Py_XDECREF(mkw);
188-
Py_DECREF(bases);
189-
return NULL;
183+
goto error;
190184
}
191185
if (winner != meta) {
192186
Py_DECREF(meta);
@@ -208,10 +202,7 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs,
208202
Py_DECREF(prep);
209203
}
210204
if (ns == NULL) {
211-
Py_DECREF(meta);
212-
Py_XDECREF(mkw);
213-
Py_DECREF(bases);
214-
return NULL;
205+
goto error;
215206
}
216207
if (!PyMapping_Check(ns)) {
217208
PyErr_Format(PyExc_TypeError,
@@ -252,13 +243,13 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs,
252243
}
253244
error:
254245
Py_XDECREF(cell);
255-
Py_DECREF(ns);
256-
Py_DECREF(meta);
246+
Py_XDECREF(ns);
247+
Py_XDECREF(meta);
257248
Py_XDECREF(mkw);
258-
Py_DECREF(bases);
259249
if (bases != orig_bases) {
260250
Py_DECREF(orig_bases);
261251
}
252+
Py_DECREF(bases);
262253
return cls;
263254
}
264255

0 commit comments

Comments
 (0)