summaryrefslogtreecommitdiffstats
path: root/Objects/object.c
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2002-05-13 18:29:46 (GMT)
committerGuido van Rossum <guido@python.org>2002-05-13 18:29:46 (GMT)
commit4402241450fe679a3cc90e4491aaabee232bb4e2 (patch)
treef696f015b6c33b8cdce1c578c605ca32456f1119 /Objects/object.c
parentdf4dabd5d2a983083ebedec7174aa22cee72b154 (diff)
downloadcpython-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/object.c')
-rw-r--r--Objects/object.c22
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);