Commit d2ea4a25 authored by Thomas Heller's avatar Thomas Heller

ctypes callback functions only support 'fundamental' result types.

Check this and raise an error when something else is used - before
this change ctypes would hang or crash when such a callback was
called.  This is a partial fix for #1574584.

Will backport to release25-maint.
parent fefbc202
...@@ -101,6 +101,19 @@ class Callbacks(unittest.TestCase): ...@@ -101,6 +101,19 @@ class Callbacks(unittest.TestCase):
after = grc(o) after = grc(o)
self.failUnlessEqual((after, o), (before, 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: try:
WINFUNCTYPE WINFUNCTYPE
except NameError: except NameError:
......
...@@ -81,6 +81,10 @@ Core and builtins ...@@ -81,6 +81,10 @@ Core and builtins
Library 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 - 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 the demo2 function to be executed on its own instead of only when the
module is run as a script. module is run as a script.
......
...@@ -293,8 +293,11 @@ ffi_info *AllocFunctionCallback(PyObject *callable, ...@@ -293,8 +293,11 @@ ffi_info *AllocFunctionCallback(PyObject *callable,
p->restype = &ffi_type_void; p->restype = &ffi_type_void;
} else { } else {
StgDictObject *dict = PyType_stgdict(restype); StgDictObject *dict = PyType_stgdict(restype);
if (dict == NULL) if (dict == NULL || dict->setfunc == NULL) {
goto error; PyErr_SetString(PyExc_TypeError,
"invalid result type for callback function");
goto error;
}
p->setfunc = dict->setfunc; p->setfunc = dict->setfunc;
p->restype = &dict->ffi_type_pointer; p->restype = &dict->ffi_type_pointer;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment