Commits

Ronald Oussoren committed 4ba98d9

Remove unsafe use of Python C API, and fix a now broken test case

Comments (0)

Files changed (3)

pyobjc-core/Modules/objc/OC_PythonNumber.m

 
 - (void)encodeWithCoder:(NSCoder*)coder
 {
-	if (PyFloat_CheckExact(value)) {
-		/* Float is a C double and can be roundtripped using 
-		 * NSNumber.
-		 */
-		[super encodeWithCoder:coder];
-		return;
+	int use_super = 0;
+
+	PyObjC_BEGIN_WITH_GIL
+		if (PyFloat_CheckExact(value)) {
+			/* Float is a C double and can be roundtripped using 
+			 * NSNumber.
+			 */
+			use_super = 1;
 
 #if PY_MAJOR_VERSION == 2
-	} else if (PyInt_CheckExact(value)) {
-		/* Int is a C double and can be roundtripped using 
-		 * NSNumber.
-		 */
-		[super encodeWithCoder:coder];
-		return;
+		} else if (PyInt_CheckExact(value)) {
+			/* Int is a C double and can be roundtripped using 
+			 * NSNumber.
+			 */
+			use_super = 1;
 #endif
-	} else if (PyLong_CheckExact(value)) {
-		int use_super = 0;
-		PyObjC_BEGIN_WITH_GIL
+		} else if (PyLong_CheckExact(value)) {
 			/* Long object that fits in a long long */
 			(void)PyLong_AsLongLong(value);
 			if (PyErr_Occurred()) {
 			} else {
 				use_super = 1;
 			}
-		PyObjC_END_WITH_GIL
+		}
+	PyObjC_END_WITH_GIL
 
-		if (use_super) {
-			[super encodeWithCoder:coder];
-			return;
-		}
+	if (use_super) {
+		[super encodeWithCoder:coder];
+	} else {
+		PyObjC_encodeWithCoder(value, coder);
 	}
-	PyObjC_encodeWithCoder(value, coder);
 }
 
 
 
 -(Class)classForArchiver
 {
-	if (PyFloat_CheckExact(value)) {
-		/* Float is a C double and can be roundtripped using 
-		 * NSNumber.
-		 */
-		return [NSNumber class];
+	PyObjC_BEGIN_WITH_GIL
+		if (PyFloat_CheckExact(value)) {
+			/* Float is a C double and can be roundtripped using 
+			 * NSNumber.
+			 */
+			PyObjC_GIL_RETURN([NSNumber class]);
 
 #if PY_MAJOR_VERSION == 2
-	} else if (PyInt_CheckExact(value)) {
-		/* Int is a C double and can be roundtripped using 
-		 * NSNumber.
-		 */
-		return [NSNumber class];
+		} else if (PyInt_CheckExact(value)) {
+			/* Int is a C double and can be roundtripped using 
+			 * NSNumber.
+			 */
+			PyObjC_GIL_RETURN([NSNumber class]);
 #endif
-	} else if (PyLong_CheckExact(value)) {
-		PyObjC_BEGIN_WITH_GIL
+		} else if (PyLong_CheckExact(value)) {
 			/* Long object that fits in a long long */
 			(void)PyLong_AsLongLong(value);
 			if (PyErr_Occurred()) {
 			} else {
 				PyObjC_GIL_RETURN([NSNumber class]);
 			}
-		PyObjC_END_WITH_GIL
 
-	} else {
-		return [OC_PythonNumber class];
-	}
+		} else {
+			PyObjC_GIL_RETURN([OC_PythonNumber class]);
+		}
+	PyObjC_END_WITH_GIL
 }
 
 -(Class)classForKeyedArchiver

pyobjc-core/Modules/objc/OC_PythonUnicode.m

 
 -(void)encodeWithCoder:(NSCoder*)coder
 {
-	if (PyUnicode_CheckExact(value)) {
-		[super encodeWithCoder:coder];
-	} else {
-		if ([coder allowsKeyedCoding]) {
-			[coder encodeInt32:2 forKey:@"pytype"];
+	PyObjC_BEGIN_WITH_GIL
+		if (PyUnicode_CheckExact(value)) {
+			[super encodeWithCoder:coder];
 		} else {
-			int v = 2;
-			[coder encodeValueOfObjCType:@encode(int) at:&v];
+			if ([coder allowsKeyedCoding]) {
+				[coder encodeInt32:2 forKey:@"pytype"];
+			} else {
+				int v = 2;
+				[coder encodeValueOfObjCType:@encode(int) at:&v];
+			}
+
+			PyObjC_encodeWithCoder(value, coder);
 		}
-
-		PyObjC_encodeWithCoder(value, coder);
-	}
+	PyObjC_END_WITH_GIL
 }
 
 -(NSObject*)replacementObjectForArchiver:(NSArchiver*)archiver 
  */
 -(Class)classForArchiver
 {
-	if (PyUnicode_CheckExact(value)) {
-		return [NSString class];
-	} else {
-		return [OC_PythonUnicode class];
-	}
+	PyObjC_BEGIN_WITH_GIL
+		if (PyUnicode_CheckExact(value)) {
+			PyObjC_GIL_RETURN([NSString class]);
+		} else {
+			PyObjC_GIL_RETURN([OC_PythonUnicode class]);
+		}
+	PyObjC_END_WITH_GIL
 }
 
 -(Class)classForKeyedArchiver
 {
-	if (PyUnicode_CheckExact(value)) {
-		return [NSString class];
-	} else {
-		return [OC_PythonUnicode class];
-	}
+	return [self classForArchiver];
 }
 
 -(Class)classForCoder
 {
-	if (PyUnicode_CheckExact(value)) {
-		return [NSString class];
-	} else {
-		return [OC_PythonUnicode class];
-	}
+	return [self classForArchiver];
 }
 
 -(Class)classForPortCoder
 {
-	if (PyUnicode_CheckExact(value)) {
-		return [NSString class];
-	} else {
-		return [OC_PythonUnicode class];
-	}
+	return [self classForArchiver];
 }
 
 /* Ensure that we can be unarchived as a generic string by pure ObjC

pyobjc-core/PyObjCTest/test_archive_python.py

 
     def test_unknown_type(self):
         try:
-            orig = pycoder.decode_dispatch[pycoder.kOP_FLOAT_STR]
-            del pycoder.decode_dispatch[pycoder.kOP_FLOAT_STR]
+            orig = pycoder.decode_dispatch[pycoder.kOP_GLOBAL]
+            del pycoder.decode_dispatch[pycoder.kOP_GLOBAL]
 
-            o = 14.2
+            o = TestKeyedArchiveSimple
             buf = self.archiverClass.archivedDataWithRootObject_(o)
             self.assertRaises(pickle.UnpicklingError, self.unarchiverClass.unarchiveObjectWithData_, buf)
 
 
         finally:
-            pycoder.decode_dispatch[pycoder.kOP_FLOAT_STR] = orig
+            pycoder.decode_dispatch[pycoder.kOP_GLOBAL] = orig
 
 
 
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.