[Python-checkins] bpo-45385: Fix reference leak from descr_check (GH-28719) (GH-28779)
corona10
webhook-mailer at python.org
Thu Oct 7 03:48:17 EDT 2021
https://github.com/python/cpython/commit/35d4857375b6ef8f1243db4da9c2cba0bee63ad6
commit: 35d4857375b6ef8f1243db4da9c2cba0bee63ad6
branch: 3.10
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: corona10 <donghee.na92 at gmail.com>
date: 2021-10-07T16:48:00+09:00
summary:
bpo-45385: Fix reference leak from descr_check (GH-28719) (GH-28779)
files:
A Misc/NEWS.d/next/Core and Builtins/2021-10-06-21-20-11.bpo-45385.CTUT8s.rst
M Objects/descrobject.c
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 0000000000000..8047c102634f0
--- /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 57a9607d10c31..97669bef368da 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)) {
More information about the Python-checkins
mailing list