summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOren Milman <orenmn@gmail.com>2018-05-09 21:38:56 (GMT)
committerSteve Dower <steve.dower@microsoft.com>2018-05-09 21:38:56 (GMT)
commitd518d8bc8d5dac1a1270612f424d33e0e5afc2b5 (patch)
treeb532e2e0677ccb8106a20e0c10411fc84c1e14c5
parent8cf4b34b3665b8bb39ea7111e6b5c3410899d3e4 (diff)
downloadcpython-d518d8bc8d5dac1a1270612f424d33e0e5afc2b5.zip
cpython-d518d8bc8d5dac1a1270612f424d33e0e5afc2b5.tar.gz
cpython-d518d8bc8d5dac1a1270612f424d33e0e5afc2b5.tar.bz2
bpo-21983: Fix a crash in ctypes.cast() when passed a ctypes structured data type (GH-3859)
-rw-r--r--Lib/ctypes/test/test_cast.py13
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2017-10-02-21-02-14.bpo-21983.UoC319.rst2
-rw-r--r--Modules/_ctypes/_ctypes.c2
3 files changed, 16 insertions, 1 deletions
diff --git a/Lib/ctypes/test/test_cast.py b/Lib/ctypes/test/test_cast.py
index 187d2bd..6878f97 100644
--- a/Lib/ctypes/test/test_cast.py
+++ b/Lib/ctypes/test/test_cast.py
@@ -82,5 +82,18 @@ class Test(unittest.TestCase):
self.assertEqual(cast(cast(s, c_void_p), c_wchar_p).value,
"hiho")
+ def test_bad_type_arg(self):
+ # The type argument must be a ctypes pointer type.
+ array_type = c_byte * sizeof(c_int)
+ array = array_type()
+ self.assertRaises(TypeError, cast, array, None)
+ self.assertRaises(TypeError, cast, array, array_type)
+ class Struct(Structure):
+ _fields_ = [("a", c_int)]
+ self.assertRaises(TypeError, cast, array, Struct)
+ class MyUnion(Union):
+ _fields_ = [("a", c_int)]
+ self.assertRaises(TypeError, cast, array, MyUnion)
+
if __name__ == "__main__":
unittest.main()
diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-10-02-21-02-14.bpo-21983.UoC319.rst b/Misc/NEWS.d/next/Core and Builtins/2017-10-02-21-02-14.bpo-21983.UoC319.rst
new file mode 100644
index 0000000..88a0368
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2017-10-02-21-02-14.bpo-21983.UoC319.rst
@@ -0,0 +1,2 @@
+Fix a crash in `ctypes.cast()` in case the type argument is a ctypes
+structured data type. Patch by Eryk Sun and Oren Milman.
diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c
index 93e8d8d..5bf49ac 100644
--- a/Modules/_ctypes/_ctypes.c
+++ b/Modules/_ctypes/_ctypes.c
@@ -5319,7 +5319,7 @@ cast_check_pointertype(PyObject *arg)
if (PyCFuncPtrTypeObject_Check(arg))
return 1;
dict = PyType_stgdict(arg);
- if (dict) {
+ if (dict != NULL && dict->proto != NULL) {
if (PyUnicode_Check(dict->proto)
&& (strchr("sPzUZXO", PyUnicode_AsUTF8(dict->proto)[0]))) {
/* simple pointer types, c_void_p, c_wchar_p, BSTR, ... */