Commits

Ronald Oussoren committed 9df2815

Fix for pychecker problems + unittests

The remaining problems involved usage of _NSZombie and some unguarded
calls into ObjC.

Comments (0)

Files changed (3)

pyobjc/Lib/objc/test/test_methodaccess.py

 
 class MethodAccessTest (unittest.TestCase):
 
+    def testObjCObject(self):
+        # Trying to access the methods of objc.objc_object should not 
+        # crash the interpreter.
+        self.assertRaises(AttributeError, getattr, objc.objc_object.pyobjc_classMethods, 'func_code')
+        self.assertRaises(AttributeError, getattr, objc.objc_object.pyobjc_instanceMethods, 'func_code')
+
+    def testNSProxyStuff(self):
+        # NSProxy is incompatitble with pyobjc_{class,instance}Methods, but 
+        # this should not crash the interpreter
+        self.assertRaises(AttributeError, getattr, objc.runtime.NSProxy.pyobjc_instanceMethods, 'foobar')
+        self.assertRaises(AttributeError, getattr, objc.runtime.NSProxy.pyobjc_classMethods, 'foobar')
+        self.assertRaises(AttributeError, getattr, objc.runtime.NSProxy, 'foobar')
+
+    def testNSZombie(self):
+        self.assertRaises(AttributeError, getattr, objc.runtime._NSZombie.pyobjc_instanceMethods, "foobar")
+        self.assertRaises(AttributeError, getattr, objc.runtime._NSZombie.pyobjc_classMethods, "foobar")
+        self.assertRaises(AttributeError, getattr, objc.runtime._NSZombie, "foobar")
+
+
     def testDir(self):
         o = objc.runtime.NSObject.new()
 

pyobjc/Modules/objc/method-accessor.m

 		return NULL;
 	}
 
-	if (class_method && strcmp(((Class)objc_object)->name, "NSProxy") == 0){
+
+	if (strcmp(GETISA(objc_object)->name, "_NSZombie") == 0) {
+		ObjCErr_Set(PyExc_AttributeError,
+			"Cannot access NSProxy.%s", name);
+		return NULL;
+	}
+
+	if (class_method && strcmp(((Class)objc_object)->name, "NSProxy") == 0 ){
 		if (sel == @selector(methodSignatureForSelector:)) {
 			ObjCErr_Set(PyExc_AttributeError,
 				"Cannot access NSProxy.%s", name);
 		}
 	}
 
+
 	NS_DURING
 		if (unbound_instance_method) {
 			methsig = [objc_object instanceMethodSignatureForSelector:sel];
 	}
 
 	if (strcmp(PyString_AS_STRING(name), "__dict__") == 0) {
+
 		PyObject* dict;
 		dict = make_dict(self->base, self->class_method);
 		return dict;
 		return NULL;
 	}
 
+
 	result = PyObject_GenericGetAttr((PyObject*)self, name);
 	if (result == NULL) {
 		PyErr_Clear();

pyobjc/Modules/objc/selector.m

 PyObjCSelector_FindNative(PyObject* self, const char* name)
 {
 	SEL   sel = PyObjCSelector_DefaultSelector(name);
+	PyObject* retval;
 
 	NSMethodSignature* methsig;
 	char  buf[1024];
 				"No attribute %s", name);
 			return NULL;
 		}
+		if (strcmp(cls->name, "_NSZombie") == 0) {
+			ObjCErr_Set(PyExc_AttributeError,
+				"No attribute %s", name);
+			return NULL;
+		}
 
 		if (strcmp(cls->name, "NSProxy") == 0) {
 			if (sel == @selector(methodSignatureForSelector:)) {
 			}
 		}
 
-		if ([cls instancesRespondToSelector:sel]) {
-			methsig = [cls instanceMethodSignatureForSelector:sel];
-			return PyObjCSelector_NewNative(cls, sel, 
-				PyObjC_NSMethodSignatureToTypeString(methsig, buf, sizeof(buf)), 0);
-		} else if ((cls != Object_class) && nil != (methsig = [(NSObject*)cls methodSignatureForSelector:sel])) {
-			return PyObjCSelector_NewNative(cls, sel, 
-				PyObjC_NSMethodSignatureToTypeString(
-					methsig, buf, sizeof(buf)), 1);
-		} else {
+		NS_DURING
+			if ([cls instancesRespondToSelector:sel]) {
+				methsig = [cls instanceMethodSignatureForSelector:sel];
+				retval = PyObjCSelector_NewNative(cls, sel, 
+					PyObjC_NSMethodSignatureToTypeString(methsig, buf, sizeof(buf)), 0);
+			} else if ((cls != Object_class) && nil != (methsig = [(NSObject*)cls methodSignatureForSelector:sel])) {
+				retval = PyObjCSelector_NewNative(cls, sel, 
+					PyObjC_NSMethodSignatureToTypeString(
+						methsig, buf, sizeof(buf)), 1);
+			} else {
+				ObjCErr_Set(PyExc_AttributeError,
+					"No attribute %s", name);
+				retval = NULL;
+			}
+		NS_HANDLER
 			ObjCErr_Set(PyExc_AttributeError,
 				"No attribute %s", name);
-			return NULL;
-		}
+			retval = NULL;
+
+		NS_ENDHANDLER
+
+		return retval;
+
 	} else if (PyObjCObject_Check(self)) {
 		id object;