diff options
author | Pablo Galindo Salgado <Pablogsal@gmail.com> | 2021-08-07 10:10:14 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-08-07 10:10:14 (GMT) |
commit | a40675c659cd8c0699f85ee9ac31660f93f8c2f5 (patch) | |
tree | 67a61b5eff447e081132b3d20765e270a6548592 | |
parent | 17c23167942498296f0bdfffe52e72d53d66d693 (diff) | |
download | cpython-a40675c659cd8c0699f85ee9ac31660f93f8c2f5.zip cpython-a40675c659cd8c0699f85ee9ac31660f93f8c2f5.tar.gz cpython-a40675c659cd8c0699f85ee9ac31660f93f8c2f5.tar.bz2 |
bpo-44856: Possible reference leak in error paths of update_bases() and __build_class__ (GH-27647)
-rw-r--r-- | Misc/NEWS.d/next/Core and Builtins/2021-08-07-01-26-12.bpo-44856.9rk3li.rst | 1 | ||||
-rw-r--r-- | Python/bltinmodule.c | 35 |
2 files changed, 14 insertions, 22 deletions
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 0000000..1111d01 --- /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 bfe21ad..761dc08 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -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 copy previously encountered bases. */ if (!(new_bases = PyList_New(i))) { + Py_DECREF(new_base); goto error; } 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); if (PyList_SetSlice(new_bases, j, j, new_base) < 0) { + Py_DECREF(new_base); goto error; } Py_DECREF(new_base); @@ -103,8 +105,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) { @@ -141,26 +144,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) { @@ -183,10 +180,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); @@ -208,10 +202,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, @@ -252,13 +243,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; } |