summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2021-10-07 07:48:00 (GMT)
committerGitHub <noreply@github.com>2021-10-07 07:48:00 (GMT)
commit35d4857375b6ef8f1243db4da9c2cba0bee63ad6 (patch)
tree7f4e04c1559c37c4e85b2ad6b1644578d25f1baa
parentce121fd8755d4db9511ce4aab39d0577165e118e (diff)
downloadcpython-35d4857375b6ef8f1243db4da9c2cba0bee63ad6.zip
cpython-35d4857375b6ef8f1243db4da9c2cba0bee63ad6.tar.gz
cpython-35d4857375b6ef8f1243db4da9c2cba0bee63ad6.tar.bz2
bpo-45385: Fix reference leak from descr_check (GH-28719) (GH-28779)
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2021-10-06-21-20-11.bpo-45385.CTUT8s.rst1
-rw-r--r--Objects/descrobject.c76
2 files changed, 38 insertions, 39 deletions
diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-10-06-21-20-11.bpo-45385.CTUT8s.rst b/Misc/NEWS.d/next/Core and Builtins/2021-10-06-21-20-11.bpo-45385.CTUT8s.rst
new file mode 100644
index 0000000..8047c10
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2021-10-06-21-20-11.bpo-45385.CTUT8s.rst
@@ -0,0 +1 @@
+Fix reference leak from descr_check. Patch by Dong-hee Na.
diff --git a/Objects/descrobject.c b/Objects/descrobject.c
index 57a9607..97669be 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)) {