From a40d57366432cd65915b92fe3e6bfe1d5ad63be0 Mon Sep 17 00:00:00 2001 From: Amaury Forgeot d'Arc Date: Mon, 12 Jan 2009 23:36:55 +0000 Subject: #3720: Interpreter crashes when an evil iterator removes its own next function. Now the slot is filled with a function that always raises. Will not backport: extensions compiled with 2.6.x would not run on 2.6.0. --- Objects/abstract.c | 1 - Objects/object.c | 14 ++++++++++++++ Objects/typeobject.c | 6 +++++- 3 files changed, 19 insertions(+), 2 deletions(-) (limited to 'Objects') diff --git a/Objects/abstract.c b/Objects/abstract.c index 956c4f4996..80a1289138 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -3067,7 +3067,6 @@ PyObject * PyIter_Next(PyObject *iter) { PyObject *result; - assert(PyIter_Check(iter)); result = (*iter->ob_type->tp_iternext)(iter); if (result == NULL && PyErr_Occurred() && diff --git a/Objects/object.c b/Objects/object.c index 1e0db4ac69..ba736a9d93 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -1305,6 +1305,20 @@ PyObject_SelfIter(PyObject *obj) return obj; } +/* Helper used when the __next__ method is removed from a type: + tp_iternext is never NULL and can be safely called without checking + on every iteration. + */ + +PyObject * +_PyObject_NextNotImplemented(PyObject *self) +{ + PyErr_Format(PyExc_TypeError, + "'%.200s' object is not iterable", + Py_TYPE(self)->tp_name); + return NULL; +} + /* Generic GetAttr functions - put these in your tp_[gs]etattro slot */ PyObject * diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 3f790e8824..8242242d19 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -6090,8 +6090,12 @@ update_one_slot(PyTypeObject *type, slotdef *p) } do { descr = _PyType_Lookup(type, p->name_strobj); - if (descr == NULL) + if (descr == NULL) { + if (ptr == (void**)&type->tp_iternext) { + specific = _PyObject_NextNotImplemented; + } continue; + } if (Py_TYPE(descr) == &PyWrapperDescr_Type) { void **tptr = resolve_slotdups(type, p->name_strobj); if (tptr == NULL || tptr == ptr) -- cgit v1.2.1