8000 bpo-44856: Possible reference leak in error paths of update_bases() a… · python/cpython@0a42309 · GitHub
[go: up one dir, main page]

Skip to content

Commit 0a42309

Browse files
bpo-44856: Possible reference leak in error paths of update_bases() and __build_class__ (GH-27647) (GH-27652)
(cherry picked from commit a40675c) Co-authored-by: Pablo Galindo Salgado <Pablogsal@gmail.com>
1 parent af441df commit 0a42309
< 8000 div class="d-flex flex-column gap-2" id="diff_file_tree" tabindex="-1">

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
@@ -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. */
7373
if (!(new_bases = PyList_New(i))) {
74+
Py_DECREF(new_base);
7475
goto error;
7576
}
7677
for (j = 0; j < i; j++) {
@@ -81,6 +82,7 @@ update_bases(PyObject *bases, PyObject *const *args, Py_ssize_t nargs)
8182
}
8283
j = PyList_GET_SIZE(new_bases);
8384
if (PyList_SetSlice(new_bases, j, j, new_base) < 0) {
85+
Py_DECREF(new_base);
8486
goto error;
8587
}
8688
Py_DECREF(new_base);
@@ -102,8 +104,9 @@ static PyObject *
102104
builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs,
103105
PyObject *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;
107110
int isclass = 0; /* initialize to prevent gcc warning */
108111

109112
if (nargs < 2) {
@@ -140,26 +143,20 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs,
140143
else {
141144
mkw = _PyStack_AsDict(args + nargs, kwnames);
142145
if (mkw == NULL) {
143-
Py_DECREF(bases);
144-
return NULL;
146+
goto error;
145147
}
146148

147149
meta = _PyDict_GetItemIdWithError(mkw, &PyId_metaclass);
148150
if (meta != NULL) {
149151
Py_INCREF(meta);
150152
if (_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 */
157156
isclass = PyType_Check(meta);
158157
}
159158
else if (PyErr_Occurred()) {
160-
Py_DECREF(mkw);
161-
Py_DECREF(bases);
162-
return NULL;
159+
goto error;
163160
}
164161
}
165162
if (meta == NULL) {
@@ -182,10 +179,7 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs,
182179
winner = (PyObject *)_PyType_CalculateMetaclass((PyTypeObject *)meta,
183180
bases);
184181
if (winner == NULL) {
185-
Py_DECREF(meta);
186-
Py_XDECREF(mkw);
187-
Py_DECREF(bases);
188-
return NULL;
182+
goto error;
189183
}
190184
if (winner != meta) {
191185
Py_DECREF(meta);
@@ -207,10 +201,7 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs,
207201
Py_DECREF(prep);
208202
}
209203
if (ns == NULL) {
210-
Py_DECREF(meta);
211-
Py_XDECREF(mkw);
212-
Py_DECREF(bases);
213-
return NULL;
204+
goto error;
214205
}
215206
if (!PyMapping_Check(ns)) {
216207
PyErr_Format(PyExc_TypeError,
@@ -251,13 +242,13 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs,
251242
}
252243
error:
253244
Py_XDECREF(cell);
254-
Py_DECREF(ns);
255-
Py_DECREF(meta);
245+
Py_XDECREF(ns);
246+
Py_XDECREF(meta);
256247
Py_XDECREF(mkw);
257-
Py_DECREF(bases);
258248
if (bases != orig_bases) {
259249
Py_DECREF(orig_bases);
260250
}
251+
Py_DECREF(bases);
261252
return cls;
262253
}
263254

0 commit comments

Comments
 (0)
0