Skip to content

Commit e6ff4eb

Browse files
authored
bpo-45385: Fix reference leak from descr_check (#28719)
1 parent 5f401f1 commit e6ff4eb

File tree

2 files changed

+38
-39
lines changed

2 files changed

+38
-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: 37 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,12 @@ 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+
return Py_NewRef(descr);
136+
}
137+
if (descr_check((PyDescrObject *)descr, obj) < 0) {
138+
return NULL;
139+
}
144140
if (descr->d_method->ml_flags & METH_METHOD) {
145141
if (PyType_Check(type)) {
146142
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)
159155
static PyObject *
160156
member_get(PyMemberDescrObject *descr, PyObject *obj, PyObject *type)
161157
{
162-
PyObject *res;
163-
164-
if (descr_check((PyDescrObject *)descr, obj, &res))
165-
return res;
158+
if (obj == NULL) {
159+
return Py_NewRef(descr);
160+
}
161+
if (descr_check((PyDescrObject *)descr, obj) < 0) {
162+
return NULL;
163+
}
166164

167165
if (descr->d_member->flags & PY_AUDIT_READ) {
168166
if (PySys_Audit("object.__getattr__", "Os",
@@ -177,10 +175,12 @@ member_get(PyMemberDescrObject *descr, PyObject *obj, PyObject *type)
177175
static PyObject *
178176
getset_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type)
179177
{
180-
PyObject *res;
181-
182-
if (descr_check((PyDescrObject *)descr, obj, &res))
183-
return res;
178+
if (obj == NULL) {
179+
return Py_NewRef(descr);
180+
}
181+
if (descr_check((PyDescrObject *)descr, obj) < 0) {
182+
return NULL;
183+
}
184184
if (descr->d_getset->get != NULL)
185185
return descr->d_getset->get(obj, descr->d_getset->closure);
186186
PyErr_Format(PyExc_AttributeError,
@@ -193,16 +193,17 @@ getset_get(PyGetSetDescrObject *descr, PyObject *obj, PyObject *type)
193193
static PyObject *
194194
wrapperdescr_get(PyWrapperDescrObject *descr, PyObject *obj, PyObject *type)
195195
{
196-
PyObject *res;
197-
198-
if (descr_check((PyDescrObject *)descr, obj, &res))
199-
return res;
196+
if (obj == NULL) {
197+
return Py_NewRef(descr);
198+
}
199+
if (descr_check((PyDescrObject *)descr, obj) < 0) {
200+
return NULL;
201+
}
200202
return PyWrapper_New((PyObject *)descr, obj);
201203
}
202204

203205
static int
204-
descr_setcheck(PyDescrObject *descr, PyObject *obj, PyObject *value,
205-
int *pres)
206+
descr_setcheck(PyDescrObject *descr, PyObject *obj, PyObject *value)
206207
{
207208
assert(obj != NULL);
208209
if (!PyObject_TypeCheck(obj, descr->d_type)) {
@@ -212,32 +213,30 @@ descr_setcheck(PyDescrObject *descr, PyObject *obj, PyObject *value,
212213
descr_name(descr), "?",
213214
descr->d_type->tp_name,
214215
Py_TYPE(obj)->tp_name);
215-
*pres = -1;
216-
return 1;
216+
return -1;
217217
}
218218
return 0;
219219
}
220220

221221
static int
222222
member_set(PyMemberDescrObject *descr, PyObject *obj, PyObject *value)
223223
{
224-
int res;
225-
226-
if (descr_setcheck((PyDescrObject *)descr, obj, value, &res))
227-
return res;
224+
if (descr_setcheck((PyDescrObject *)descr, obj, value) < 0) {
225+
return -1;
226+
}
228227
return PyMember_SetOne((char *)obj, descr->d_member, value);
229228
}
230229

231230
static int
232231
getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value)
233232
{
234-
int res;
235-
236-
if (descr_setcheck((PyDescrObject *)descr, obj, value, &res))
237-
return res;
238-
if (descr->d_getset->set != NULL)
233+
if (descr_setcheck((PyDescrObject *)descr, obj, value) < 0) {
234+
return -1;
235+
}
236+
if (descr->d_getset->set != NULL) {
239237
return descr->d_getset->set(obj, value,
240238
descr->d_getset->closure);
239+
}
241240
PyErr_Format(PyExc_AttributeError,
242241
"attribute '%V' of '%.100s' objects is not writable",
243242
descr_name((PyDescrObject *)descr), "?",
@@ -264,8 +263,7 @@ method_check_args(PyObject *func, PyObject *const *args, Py_ssize_t nargs, PyObj
264263
return -1;
265264
}
266265
PyObject *self = args[0];
267-
PyObject *dummy;
268-
if (descr_check((PyDescrObject *)func, self, &dummy)) {
266+
if (descr_check((PyDescrObject *)func, self) < 0) {
269267
return -1;
270268
}
271269
if (kwnames && PyTuple_GET_SIZE(kwnames)) {

0 commit comments

Comments
 (0)