mirror of
https://github.com/python/cpython.git
synced 2025-12-04 00:30:19 +00:00
Jim Fulton reported a segfault in dir(). A heavily proxied object
returned a proxy for __class__ whose __bases__ was also a proxy. The merge_class_dict() helper for dir() assumed incorrectly that __bases__ would always be a tuple and used the in-line tuple API on the proxy. I will backport this to 2.2 as well.
This commit is contained in:
parent
df4dabd5d2
commit
4402241450
2 changed files with 35 additions and 7 deletions
|
|
@ -1520,14 +1520,22 @@ merge_class_dict(PyObject* dict, PyObject* aclass)
|
|||
if (bases == NULL)
|
||||
PyErr_Clear();
|
||||
else {
|
||||
/* We have no guarantee that bases is a real tuple */
|
||||
int i, n;
|
||||
assert(PyTuple_Check(bases));
|
||||
n = PyTuple_GET_SIZE(bases);
|
||||
for (i = 0; i < n; i++) {
|
||||
PyObject *base = PyTuple_GET_ITEM(bases, i);
|
||||
if (merge_class_dict(dict, base) < 0) {
|
||||
Py_DECREF(bases);
|
||||
return -1;
|
||||
n = PySequence_Size(bases); /* This better be right */
|
||||
if (n < 0)
|
||||
PyErr_Clear();
|
||||
else {
|
||||
for (i = 0; i < n; i++) {
|
||||
PyObject *base = PySequence_GetItem(bases, i);
|
||||
if (base == NULL) {
|
||||
Py_DECREF(bases);
|
||||
return -1;
|
||||
}
|
||||
if (merge_class_dict(dict, base) < 0) {
|
||||
Py_DECREF(bases);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
Py_DECREF(bases);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue