From 817905b2393b03e035d2bbfc8d92b7bbeaddb118 Mon Sep 17 00:00:00 2001 From: R David Murray Date: Sun, 12 Oct 2014 13:54:48 -0400 Subject: [PATCH] #13096: Fix segfault in CTypes POINTER handling of large values. Patch by Meador Inge. --- Lib/ctypes/test/test_pointers.py | 8 ++++++++ Misc/NEWS | 3 +++ Modules/_ctypes/callproc.c | 10 ++++++++-- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/Lib/ctypes/test/test_pointers.py b/Lib/ctypes/test/test_pointers.py index f8ef0ab830c..4cd3a7a689c 100644 --- a/Lib/ctypes/test/test_pointers.py +++ b/Lib/ctypes/test/test_pointers.py @@ -7,6 +7,8 @@ ctype_types = [c_byte, c_ubyte, c_short, c_ushort, c_int, c_uint, c_long, c_ulong, c_longlong, c_ulonglong, c_double, c_float] python_types = [int, int, int, int, int, int, int, int, int, int, float, float] +LargeNamedType = type('T' * 2 ** 25, (Structure,), {}) +large_string = 'T' * 2 ** 25 class PointersTestCase(unittest.TestCase): @@ -188,5 +190,11 @@ class PointersTestCase(unittest.TestCase): mth = WINFUNCTYPE(None)(42, "name", (), None) self.assertEqual(bool(mth), True) + def test_pointer_type_name(self): + self.assertTrue(POINTER(LargeNamedType)) + + def test_pointer_type_str_name(self): + self.assertTrue(POINTER(large_string)) + if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS b/Misc/NEWS index a9ac0b2c839..ab5a4cb3789 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -27,6 +27,9 @@ Core and Builtins Library ------- +- Issue #13096: Fixed segfault in CTypes POINTER handling of large + values. + - Issue #11694: Raise ConversionError in xdrlib as documented. Patch by Filip GruszczyƄski and Claudiu Popa. diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index dcabbdf361d..6cf358cf89f 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -1672,24 +1672,30 @@ POINTER(PyObject *self, PyObject *cls) } if (PyUnicode_CheckExact(cls)) { char *name = _PyUnicode_AsString(cls); - buf = alloca(strlen(name) + 3 + 1); + buf = PyMem_Malloc(strlen(name) + 3 + 1); + if (buf == NULL) + return PyErr_NoMemory(); sprintf(buf, "LP_%s", name); result = PyObject_CallFunction((PyObject *)Py_TYPE(&PyCPointer_Type), "s(O){}", buf, &PyCPointer_Type); + PyMem_Free(buf); if (result == NULL) return result; key = PyLong_FromVoidPtr(result); } else if (PyType_Check(cls)) { typ = (PyTypeObject *)cls; - buf = alloca(strlen(typ->tp_name) + 3 + 1); + buf = PyMem_Malloc(strlen(typ->tp_name) + 3 + 1); + if (buf == NULL) + return PyErr_NoMemory(); sprintf(buf, "LP_%s", typ->tp_name); result = PyObject_CallFunction((PyObject *)Py_TYPE(&PyCPointer_Type), "s(O){sO}", buf, &PyCPointer_Type, "_type_", cls); + PyMem_Free(buf); if (result == NULL) return result; Py_INCREF(cls);