diff --git a/Lib/ctypes/test/test_callbacks.py b/Lib/ctypes/test/test_callbacks.py index 9d96a5445e2..f47fc37b3f0 100644 --- a/Lib/ctypes/test/test_callbacks.py +++ b/Lib/ctypes/test/test_callbacks.py @@ -101,6 +101,19 @@ class Callbacks(unittest.TestCase): after = grc(o) self.failUnlessEqual((after, o), (before, o)) + def test_unsupported_restype_1(self): + # Only "fundamental" result types are supported for callback + # functions, the type must have a non-NULL stgdict->setfunc. + # POINTER(c_double), for example, is not supported. + + prototype = self.functype.im_func(POINTER(c_double)) + # The type is checked when the prototype is called + self.assertRaises(TypeError, prototype, lambda: None) + + def test_unsupported_restype_2(self): + prototype = self.functype.im_func(object) + self.assertRaises(TypeError, prototype, lambda: None) + try: WINFUNCTYPE except NameError: diff --git a/Misc/NEWS b/Misc/NEWS index 9d22aedfb2c..b0f8f55a5b7 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -81,6 +81,10 @@ Core and builtins Library ------- +- ctypes callback functions only support 'fundamental' data types as + result type. Raise an error when something else is used. This is a + partial fix for Bug #1574584. + - Fix turtle so that time.sleep is imported for the entire library. Allows the demo2 function to be executed on its own instead of only when the module is run as a script. diff --git a/Modules/_ctypes/callbacks.c b/Modules/_ctypes/callbacks.c index 41ec0f50289..0e5d6c0456f 100644 --- a/Modules/_ctypes/callbacks.c +++ b/Modules/_ctypes/callbacks.c @@ -293,8 +293,11 @@ ffi_info *AllocFunctionCallback(PyObject *callable, p->restype = &ffi_type_void; } else { StgDictObject *dict = PyType_stgdict(restype); - if (dict == NULL) - goto error; + if (dict == NULL || dict->setfunc == NULL) { + PyErr_SetString(PyExc_TypeError, + "invalid result type for callback function"); + goto error; + } p->setfunc = dict->setfunc; p->restype = &dict->ffi_type_pointer; }