Commits

Ronald Oussoren committed 5ad491e

Fix crash in objc.object_property(dynamic=True) due
to unlimited recursion.

Comments (0)

Files changed (2)

pyobjc-core/Modules/objc/method-accessor.m

 	if (flattened == NULL) {
 		return NULL;
 	}
-
 	return PyObjCSelector_NewNative((Class)objc_object, sel,
 		flattened, class_method);
 }
 		}
 
 	} else {
-		if (PyObjCClass_Check(self->base)) {
+		if (PyObjCClass_Check(self->base) || PyObjCObject_Check(self->base)) {
 			/* Walk the mro and look in the class dict */
-			PyObject* mro = ((PyTypeObject*)self->base)->tp_mro;
+			PyObject* mro;
+			PyObject* descr_arg;
+			
+			if (PyObjCClass_Check(self->base)) {
+				mro = ((PyTypeObject*)self->base)->tp_mro;
+				descr_arg = NULL;
+			} else {
+				mro = (Py_TYPE(self->base))->tp_mro;
+				descr_arg = self->base;
+			}
 			Py_ssize_t i, len;
 
 			len = PyTuple_GET_SIZE(mro);
 						 * descriptor mechanism to
 						 * fetch the actual result
 						 */
-						v = Py_TYPE(v)->tp_descr_get(v, NULL, (PyObject*)Py_TYPE(v));
+						v = Py_TYPE(v)->tp_descr_get(v, descr_arg, (PyObject*)Py_TYPE(v));
 						result = v;
 						Py_INCREF(result);
-						break;
 					}
+					/* Found an item with the specified 
+					 * name, abort the search.
+					 */
+					break;
 				}
 			}
 	
 	if (self->class_method && PyObjCObject_Check(self->base)) {
 		/* Class method */
 		((PyObjCSelector*)result)->sel_self = (PyObject*)(Py_TYPE(self->base));
+		Py_INCREF(Py_TYPE(self->base));
 	} else if (!self->class_method && PyObjCClass_Check(self->base)) {
 		/* Unbound instance method */
 		((PyObjCSelector*)result)->sel_self = NULL;
 	} else {
 		/* Bound instance method */
 		((PyObjCSelector*)result)->sel_self = self->base;
+		Py_INCREF(self->base);
+
 	}
-	Py_XINCREF(((PyObjCSelector*)result)->sel_self);
+	/*Py_XINCREF(((PyObjCSelector*)result)->sel_self);*/
 	Py_DECREF(name_bytes);
 	return result;
 }

pyobjc-core/NEWS.txt

 Version 2.3a0
 -------------
 
+- BUGFIX: accessing methods through ``anObject.pyobjc_instancMethods`` is
+  now safer, before this release this could cause unlimited recursion
+  (although I'm not sure if it was possible to trigger this without
+  other changes in this release).
+
 - The PyObjC egg now includes the header files that should be used to
   compile to compile the extensions in the framework wrappers, which makes
   it a lot easier to access those headers.
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.