mirror of
https://github.com/python/cpython.git
synced 2025-08-27 04:05:34 +00:00
bpo-44856: Possible reference leak in error paths of update_bases() and __build_class__ (GH-27647)
(cherry picked from commit a40675c659
)
Co-authored-by: Pablo Galindo Salgado <Pablogsal@gmail.com>
This commit is contained in:
parent
699ee016af
commit
ac8f72cd3f
2 changed files with 14 additions and 22 deletions
|
@ -0,0 +1 @@
|
||||||
|
Fix reference leaks in the error paths of ``update_bases()`` and ``__build_class__``. Patch by Pablo Galindo.
|
|
@ -72,6 +72,7 @@ update_bases(PyObject *bases, PyObject *const *args, Py_ssize_t nargs)
|
||||||
/* If this is a first successful replacement, create new_bases list and
|
/* If this is a first successful replacement, create new_bases list and
|
||||||
copy previously encountered bases. */
|
copy previously encountered bases. */
|
||||||
if (!(new_bases = PyList_New(i))) {
|
if (!(new_bases = PyList_New(i))) {
|
||||||
|
Py_DECREF(new_base);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
for (j = 0; j < i; j++) {
|
for (j = 0; j < i; j++) {
|
||||||
|
@ -82,6 +83,7 @@ update_bases(PyObject *bases, PyObject *const *args, Py_ssize_t nargs)
|
||||||
}
|
}
|
||||||
j = PyList_GET_SIZE(new_bases);
|
j = PyList_GET_SIZE(new_bases);
|
||||||
if (PyList_SetSlice(new_bases, j, j, new_base) < 0) {
|
if (PyList_SetSlice(new_bases, j, j, new_base) < 0) {
|
||||||
|
Py_DECREF(new_base);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
Py_DECREF(new_base);
|
Py_DECREF(new_base);
|
||||||
|
@ -103,8 +105,9 @@ static PyObject *
|
||||||
builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs,
|
builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs,
|
||||||
PyObject *kwnames)
|
PyObject *kwnames)
|
||||||
{
|
{
|
||||||
PyObject *func, *name, *bases, *mkw, *meta, *winner, *prep, *ns, *orig_bases;
|
PyObject *func, *name, *winner, *prep;
|
||||||
PyObject *cls = NULL, *cell = NULL;
|
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 */
|
int isclass = 0; /* initialize to prevent gcc warning */
|
||||||
|
|
||||||
if (nargs < 2) {
|
if (nargs < 2) {
|
||||||
|
@ -141,26 +144,20 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs,
|
||||||
else {
|
else {
|
||||||
mkw = _PyStack_AsDict(args + nargs, kwnames);
|
mkw = _PyStack_AsDict(args + nargs, kwnames);
|
||||||
if (mkw == NULL) {
|
if (mkw == NULL) {
|
||||||
Py_DECREF(bases);
|
goto error;
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
meta = _PyDict_GetItemIdWithError(mkw, &PyId_metaclass);
|
meta = _PyDict_GetItemIdWithError(mkw, &PyId_metaclass);
|
||||||
if (meta != NULL) {
|
if (meta != NULL) {
|
||||||
Py_INCREF(meta);
|
Py_INCREF(meta);
|
||||||
if (_PyDict_DelItemId(mkw, &PyId_metaclass) < 0) {
|
if (_PyDict_DelItemId(mkw, &PyId_metaclass) < 0) {
|
||||||
Py_DECREF(meta);
|
goto error;
|
||||||
Py_DECREF(mkw);
|
|
||||||
Py_DECREF(bases);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
/* metaclass is explicitly given, check if it's indeed a class */
|
/* metaclass is explicitly given, check if it's indeed a class */
|
||||||
isclass = PyType_Check(meta);
|
isclass = PyType_Check(meta);
|
||||||
}
|
}
|
||||||
else if (PyErr_Occurred()) {
|
else if (PyErr_Occurred()) {
|
||||||
Py_DECREF(mkw);
|
goto error;
|
||||||
Py_DECREF(bases);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (meta == NULL) {
|
if (meta == NULL) {
|
||||||
|
@ -183,10 +180,7 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs,
|
||||||
winner = (PyObject *)_PyType_CalculateMetaclass((PyTypeObject *)meta,
|
winner = (PyObject *)_PyType_CalculateMetaclass((PyTypeObject *)meta,
|
||||||
bases);
|
bases);
|
||||||
if (winner == NULL) {
|
if (winner == NULL) {
|
||||||
Py_DECREF(meta);
|
goto error;
|
||||||
Py_XDECREF(mkw);
|
|
||||||
Py_DECREF(bases);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
if (winner != meta) {
|
if (winner != meta) {
|
||||||
Py_DECREF(meta);
|
Py_DECREF(meta);
|
||||||
|
@ -208,10 +202,7 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs,
|
||||||
Py_DECREF(prep);
|
Py_DECREF(prep);
|
||||||
}
|
}
|
||||||
if (ns == NULL) {
|
if (ns == NULL) {
|
||||||
Py_DECREF(meta);
|
goto error;
|
||||||
Py_XDECREF(mkw);
|
|
||||||
Py_DECREF(bases);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
if (!PyMapping_Check(ns)) {
|
if (!PyMapping_Check(ns)) {
|
||||||
PyErr_Format(PyExc_TypeError,
|
PyErr_Format(PyExc_TypeError,
|
||||||
|
@ -252,13 +243,13 @@ builtin___build_class__(PyObject *self, PyObject *const *args, Py_ssize_t nargs,
|
||||||
}
|
}
|
||||||
error:
|
error:
|
||||||
Py_XDECREF(cell);
|
Py_XDECREF(cell);
|
||||||
Py_DECREF(ns);
|
Py_XDECREF(ns);
|
||||||
Py_DECREF(meta);
|
Py_XDECREF(meta);
|
||||||
Py_XDECREF(mkw);
|
Py_XDECREF(mkw);
|
||||||
Py_DECREF(bases);
|
|
||||||
if (bases != orig_bases) {
|
if (bases != orig_bases) {
|
||||||
Py_DECREF(orig_bases);
|
Py_DECREF(orig_bases);
|
||||||
}
|
}
|
||||||
|
Py_DECREF(bases);
|
||||||
return cls;
|
return cls;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue