Skip to content

Commit 660718d

Browse files
authored
[3.9] bpo-45385: Fix reference leak from descr_check (GH-28719) (GH-28780)
(cherry picked from commit e6ff4eb) Co-authored-by: Dong-hee Na <[email protected]>
1 parent 4f161e6 commit 660718d

File tree

2 files changed

+42
-39
lines changed

2 files changed

+42
-39
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix reference leak from descr_check. Patch by Dong-hee Na.

Objects/descrobject.c

Lines changed: 41 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -72,22 +72,16 @@ wrapperdescr_repr(PyWrapperDescrObject *descr)
7272
}
7373

7474
static int
75-
descr_check(PyDescrObject *descr, PyObject *obj, PyObject **pres)
75+
descr_check(PyDescrObject *descr, PyObject *obj)
7676
{
77-
if (obj == NULL) {
78-
Py_INCREF(descr);
79-
*pres = (PyObject *)descr;
80-
return 1;
81-
}
8277
if (!PyObject_TypeCheck(obj, descr->d_type)) {
8378
PyErr_Format(PyExc_TypeError,
8479
"descriptor '%V' for '%.100s' objects "
8580
"doesn't apply to a '%.100s' object",
8681
descr_name((PyDescrObject *)descr), "?",
8782
descr->d_type->tp_name,
8883
Py_TYPE(obj)->tp_name);
89-
*pres = NULL;
90-
return 1;
84+
return -1;
9185
}
9286
return 0;
9387
}
@@ -137,10 +131,13 @@ classmethod_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type)
137131
static PyObject *
138132
method_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type)
139133
{
140-
PyObject *res;
141-
142-
if (descr_check((PyDescrObject *)descr, obj, &res))
143-
return res;
134+
if (obj == NULL) {
135+
Py_INCREF(descr);
136+
return (PyObject *)descr;
137+
}
138+
if (descr_check((PyDescrObject *)descr, obj) < 0) {
139+
return NULL;
140+
}
144141
if (descr->d_method->ml_flags & METH_METHOD) {
145142
if (PyType_Check(type)) {
146143
return PyCMethod_New(descr->d_method, obj, NULL, descr->d_common.d_type);
@@ -159,10 +156,13 @@ method_get(PyMethodDescrObject *descr, PyObject *obj, PyObject *type)
159156
static PyObject *
160157
member_get(PyMemberDescrObject *descr, PyObject *obj, PyObject *type)
161158
{
162-
PyObject *res;
163-
164-
if (descr_check((PyDescrObject *)descr, obj, &res))
165-
return res;
159+
if (obj == NULL) {
160+
Py_INCREF(descr);
161+
return (PyObject *)descr;
162+
}
163+
if (descr_check((PyDescrObject *)descr, obj) < 0) {
164+
return NULL;
165+
}
166166

167167
if (descr->d_member->flags & READ_RESTRICTED) {
168168
if (PySys_Audit("object.__getattr__", "Os",
@@ -177,10 +177,13 @@ member_get(PyMemberDescrObject *descr, PyObject *obj, PyObject *type)
177177
static PyObject *
178178
getset_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type)
179179
{
180-
PyObject *res;
181-
182-
if (descr_check((PyDescrObject *)descr, obj, &res))
183-
return res;
180+
if (obj == NULL) {
181+
Py_INCREF(descr);
182+
return (PyObject *)descr;
183+
}
184+
if (descr_check((PyDescrObject *)descr, obj) < 0) {
185+
return NULL;
186+
}
184187
if (descr->d_getset->get != NULL)
185188
return descr->d_getset->get(obj, descr->d_getset->closure);
186189
PyErr_Format(PyExc_AttributeError,
@@ -193,16 +196,18 @@ getset_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type)
193196
static PyObject *
194197
wrapperdescr_get(PyWrapperDescrObject *descr, PyObject *obj, PyObject *type)
195198
{
196-
PyObject *res;
197-
198-
if (descr_check((PyDescrObject *)descr, obj, &res))
199-
return res;
199+
if (obj == NULL) {
200+
Py_INCREF(descr);
201+
return (PyObject *)descr;
202+
}
203+
if (descr_check((PyDescrObject *)descr, obj) < 0) {
204+
return NULL;
205+
}
200206
return PyWrapper_New((PyObject *)descr, obj);
201207
}
202208

203209
static int
204-
descr_setcheck(PyDescrObject *descr, PyObject *obj, PyObject *value,
205-
int *pres)
210+
descr_setcheck(PyDescrObject *descr, PyObject *obj, PyObject *value)
206211
{
207212
assert(obj != NULL);
208213
if (!PyObject_TypeCheck(obj, descr->d_type)) {
@@ -212,32 +217,30 @@ descr_setcheck(PyDescrObject *descr, PyObject *obj, PyObject *value,
212217
descr_name(descr), "?",
213218
descr->d_type->tp_name,
214219
Py_TYPE(obj)->tp_name);
215-
*pres = -1;
216-
return 1;
220+
return -1;
217221
}
218222
return 0;
219223
}
220224

221225
static int
222226
member_set(PyMemberDescrObject *descr, PyObject *obj, PyObject *value)
223227
{
224-
int res;
225-
226-
if (descr_setcheck((PyDescrObject *)descr, obj, value, &res))
227-
return res;
228+
if (descr_setcheck((PyDescrObject *)descr, obj, value) < 0) {
229+
return -1;
230+
}
228231
return PyMember_SetOne((char *)obj, descr->d_member, value);
229232
}
230233

231234
static int
232235
getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value)
233236
{
234-
int res;
235-
236-
if (descr_setcheck((PyDescrObject *)descr, obj, value, &res))
237-
return res;
238-
if (descr->d_getset->set != NULL)
237+
if (descr_setcheck((PyDescrObject *)descr, obj, value) < 0) {
238+
return -1;
239+
}
240+
if (descr->d_getset->set != NULL) {
239241
return descr->d_getset->set(obj, value,
240242
descr->d_getset->closure);
243+
}
241244
PyErr_Format(PyExc_AttributeError,
242245
"attribute '%V' of '%.100s' objects is not writable",
243246
descr_name((PyDescrObject *)descr), "?",
@@ -264,8 +267,7 @@ method_check_args(PyObject *func, PyObject *const *args, Py_ssize_t nargs, PyObj
264267
return -1;
265268
}
266269
PyObject *self = args[0];
267-
PyObject *dummy;
268-
if (descr_check((PyDescrObject *)func, self, &dummy)) {
270+
if (descr_check((PyDescrObject *)func, self) < 0) {
269271
return -1;
270272
}
271273
if (kwnames && PyTuple_GET_SIZE(kwnames)) {

0 commit comments

Comments
 (0)