diff options
author | Guido van Rossum <guido@python.org> | 2002-05-13 18:29:46 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2002-05-13 18:29:46 (GMT) |
commit | 4402241450fe679a3cc90e4491aaabee232bb4e2 (patch) | |
tree | f696f015b6c33b8cdce1c578c605ca32456f1119 /Objects | |
parent | df4dabd5d2a983083ebedec7174aa22cee72b154 (diff) | |
download | cpython-4402241450fe679a3cc90e4491aaabee232bb4e2.zip cpython-4402241450fe679a3cc90e4491aaabee232bb4e2.tar.gz cpython-4402241450fe679a3cc90e4491aaabee232bb4e2.tar.bz2 |
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.
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/object.c | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/Objects/object.c b/Objects/object.c index 85fd35f..1bd8db9 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -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); |