mirror of https://github.com/python/cpython
bpo-45385: Fix reference leak from descr_check (#28719)
This commit is contained in:
parent
5f401f1040
commit
e6ff4eba6d
|
@ -0,0 +1 @@
|
|||
Fix reference leak from descr_check. Patch by Dong-hee Na.
|
|
@ -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)) {
|
||||
|
|
Loading…
Reference in New Issue