Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2d01dc0

Browse files
committed
Issue #14211: _PyObject_GenericSetAttrWithDict() keeps a strong reference to
the descriptor because it may be destroyed before being used, destroyed during the update of the dict for example.
1 parent d74782b commit 2d01dc0

2 files changed

Lines changed: 5 additions & 33 deletions

File tree

Lib/test/crashers/borrowed_ref_1.py

Lines changed: 0 additions & 29 deletions
This file was deleted.

Objects/object.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1074,7 +1074,6 @@ _PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name, PyObject *dict)
10741074
f = descr->ob_type->tp_descr_get;
10751075
if (f != NULL && PyDescr_IsData(descr)) {
10761076
res = f(descr, obj, (PyObject *)obj->ob_type);
1077-
Py_DECREF(descr);
10781077
goto done;
10791078
}
10801079
}
@@ -1105,7 +1104,6 @@ _PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name, PyObject *dict)
11051104
res = PyDict_GetItem(dict, name);
11061105
if (res != NULL) {
11071106
Py_INCREF(res);
1108-
Py_XDECREF(descr);
11091107
Py_DECREF(dict);
11101108
goto done;
11111109
}
@@ -1114,20 +1112,20 @@ _PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name, PyObject *dict)
11141112

11151113
if (f != NULL) {
11161114
res = f(descr, obj, (PyObject *)Py_TYPE(obj));
1117-
Py_DECREF(descr);
11181115
goto done;
11191116
}
11201117

11211118
if (descr != NULL) {
11221119
res = descr;
1123-
/* descr was already increfed above */
1120+
descr = NULL;
11241121
goto done;
11251122
}
11261123

11271124
PyErr_Format(PyExc_AttributeError,
11281125
"'%.50s' object has no attribute '%U'",
11291126
tp->tp_name, name);
11301127
done:
1128+
Py_XDECREF(descr);
11311129
Py_DECREF(name);
11321130
return res;
11331131
}
@@ -1163,6 +1161,8 @@ _PyObject_GenericSetAttrWithDict(PyObject *obj, PyObject *name,
11631161
}
11641162

11651163
descr = _PyType_Lookup(tp, name);
1164+
Py_XINCREF(descr);
1165+
11661166
f = NULL;
11671167
if (descr != NULL) {
11681168
f = descr->ob_type->tp_descr_set;
@@ -1212,6 +1212,7 @@ _PyObject_GenericSetAttrWithDict(PyObject *obj, PyObject *name,
12121212
"'%.50s' object attribute '%U' is read-only",
12131213
tp->tp_name, name);
12141214
done:
1215+
Py_XDECREF(descr);
12151216
Py_DECREF(name);
12161217
return res;
12171218
}

0 commit comments

Comments
 (0)