diff options
author | Dong-hee Na <donghee.na@python.org> | 2021-10-07 00:51:56 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-07 00:51:56 (GMT) |
commit | e6ff4eba6da9b64aed235ba8d730b5645f71955c (patch) | |
tree | bd0bf71554647beac4607a38ddcb46b4ed7e5448 /Objects | |
parent | 5f401f10400123afa9171548c432ea3fc37c0736 (diff) | |
download | cpython-e6ff4eba6da9b64aed235ba8d730b5645f71955c.zip cpython-e6ff4eba6da9b64aed235ba8d730b5645f71955c.tar.gz cpython-e6ff4eba6da9b64aed235ba8d730b5645f71955c.tar.bz2 |
bpo-45385: Fix reference leak from descr_check (#28719)
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/descrobject.c | 76 |
1 files changed, 37 insertions, 39 deletions
diff --git a/Objects/descrobject.c b/Objects/descrobject.c index 4ed36e9..946ea6a 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -72,13 +72,8 @@ wrapperdescr_repr(PyWrapperDescrObject *descr) } static int -descr_check(PyDescrObject *descr, PyObject *obj, PyObject **pres) +descr_check(PyDescrObject *descr, PyObject *obj) { - if (obj == NULL) { - Py_INCREF(descr); - *pres = (PyObject *)descr; - return 1; - } if (!PyObject_TypeCheck(obj, descr->d_type)) { PyErr_Format(PyExc_TypeError, "descriptor '%V' for '%.100s' objects " @@ -86,8 +81,7 @@ descr_check(PyDescrObject *descr, PyObject *obj, PyObject **pres) descr_name((PyDescrObject *)descr), "?", descr->d_type->tp_name, Py_TYPE(obj)->tp_name); - *pres = NULL; - return 1; + return -1; } return 0; } @@ -137,10 +131,12 @@ classmethod_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type) static PyObject * method_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type) { - PyObject *res; - - if (descr_check((PyDescrObject *)descr, obj, &res)) - return res; + if (obj == NULL) { + return Py_NewRef(descr); + } + if (descr_check((PyDescrObject *)descr, obj) < 0) { + return NULL; + } if (descr->d_method->ml_flags & METH_METHOD) { if (PyType_Check(type)) { return PyCMethod_New(descr->d_method, obj, NULL, descr->d_common.d_type); @@ -159,10 +155,12 @@ method_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type) static PyObject * member_get(PyMemberDescrObject *descr, PyObject *obj, PyObject *type) { - PyObject *res; - - if (descr_check((PyDescrObject *)descr, obj, &res)) - return res; + if (obj == NULL) { + return Py_NewRef(descr); + } + if (descr_check((PyDescrObject *)descr, obj) < 0) { + return NULL; + } if (descr->d_member->flags & PY_AUDIT_READ) { if (PySys_Audit("object.__getattr__", "Os", @@ -177,10 +175,12 @@ member_get(PyMemberDescrObject *descr, PyObject *obj, PyObject *type) static PyObject * getset_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type) { - PyObject *res; - - if (descr_check((PyDescrObject *)descr, obj, &res)) - return res; + if (obj == NULL) { + return Py_NewRef(descr); + } + if (descr_check((PyDescrObject *)descr, obj) < 0) { + return NULL; + } if (descr->d_getset->get != NULL) return descr->d_getset->get(obj, descr->d_getset->closure); PyErr_Format(PyExc_AttributeError, @@ -193,16 +193,17 @@ getset_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type) static PyObject * wrapperdescr_get(PyWrapperDescrObject *descr, PyObject *obj, PyObject *type) { - PyObject *res; - - if (descr_check((PyDescrObject *)descr, obj, &res)) - return res; + if (obj == NULL) { + return Py_NewRef(descr); + } + if (descr_check((PyDescrObject *)descr, obj) < 0) { + return NULL; + } return PyWrapper_New((PyObject *)descr, obj); } static int -descr_setcheck(PyDescrObject *descr, PyObject *obj, PyObject *value, - int *pres) +descr_setcheck(PyDescrObject *descr, PyObject *obj, PyObject *value) { assert(obj != NULL); if (!PyObject_TypeCheck(obj, descr->d_type)) { @@ -212,8 +213,7 @@ descr_setcheck(PyDescrObject *descr, PyObject *obj, PyObject *value, descr_name(descr), "?", descr->d_type->tp_name, Py_TYPE(obj)->tp_name); - *pres = -1; - return 1; + return -1; } return 0; } @@ -221,23 +221,22 @@ descr_setcheck(PyDescrObject *descr, PyObject *obj, PyObject *value, static int member_set(PyMemberDescrObject *descr, PyObject *obj, PyObject *value) { - int res; - - if (descr_setcheck((PyDescrObject *)descr, obj, value, &res)) - return res; + if (descr_setcheck((PyDescrObject *)descr, obj, value) < 0) { + return -1; + } return PyMember_SetOne((char *)obj, descr->d_member, value); } static int getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value) { - int res; - - if (descr_setcheck((PyDescrObject *)descr, obj, value, &res)) - return res; - if (descr->d_getset->set != NULL) + if (descr_setcheck((PyDescrObject *)descr, obj, value) < 0) { + return -1; + } + if (descr->d_getset->set != NULL) { return descr->d_getset->set(obj, value, descr->d_getset->closure); + } PyErr_Format(PyExc_AttributeError, "attribute '%V' of '%.100s' objects is not writable", descr_name((PyDescrObject *)descr), "?", @@ -264,8 +263,7 @@ method_check_args(PyObject *func, PyObject *const *args, Py_ssize_t nargs, PyObj return -1; } PyObject *self = args[0]; - PyObject *dummy; - if (descr_check((PyDescrObject *)func, self, &dummy)) { + if (descr_check((PyDescrObject *)func, self) < 0) { return -1; } if (kwnames && PyTuple_GET_SIZE(kwnames)) { |