Commit 55bf20ad authored by R David Murray's avatar R David Murray

#13096: Fix segfault in CTypes POINTER handling of large values.

Patch by Meador Inge.
parent e73b8c64
...@@ -7,6 +7,8 @@ ctype_types = [c_byte, c_ubyte, c_short, c_ushort, c_int, c_uint, ...@@ -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] c_long, c_ulong, c_longlong, c_ulonglong, c_double, c_float]
python_types = [int, int, int, int, int, long, python_types = [int, int, int, int, int, long,
int, long, long, long, float, float] int, long, long, long, float, float]
LargeNamedType = type('T' * 2 ** 25, (Structure,), {})
large_string = 'T' * 2 ** 25
class PointersTestCase(unittest.TestCase): class PointersTestCase(unittest.TestCase):
...@@ -188,5 +190,11 @@ class PointersTestCase(unittest.TestCase): ...@@ -188,5 +190,11 @@ class PointersTestCase(unittest.TestCase):
mth = WINFUNCTYPE(None)(42, "name", (), None) mth = WINFUNCTYPE(None)(42, "name", (), None)
self.assertEqual(bool(mth), True) 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__': if __name__ == '__main__':
unittest.main() unittest.main()
...@@ -37,6 +37,9 @@ Core and Builtins ...@@ -37,6 +37,9 @@ Core and Builtins
Library Library
------- -------
- Issue #13096: Fixed segfault in CTypes POINTER handling of large
values.
- Issue #11694: Raise ConversionError in xdrlib as documented. Patch - Issue #11694: Raise ConversionError in xdrlib as documented. Patch
by Filip Gruszczyński and Claudiu Popa. by Filip Gruszczyński and Claudiu Popa.
......
...@@ -1807,7 +1807,9 @@ POINTER(PyObject *self, PyObject *cls) ...@@ -1807,7 +1807,9 @@ POINTER(PyObject *self, PyObject *cls)
return result; return result;
} }
if (PyString_CheckExact(cls)) { if (PyString_CheckExact(cls)) {
buf = alloca(strlen(PyString_AS_STRING(cls)) + 3 + 1); buf = PyMem_Malloc(strlen(PyString_AS_STRING(cls)) + 3 + 1);
if (buf == NULL)
return PyErr_NoMemory();
sprintf(buf, "LP_%s", PyString_AS_STRING(cls)); sprintf(buf, "LP_%s", PyString_AS_STRING(cls));
result = PyObject_CallFunction((PyObject *)Py_TYPE(&PyCPointer_Type), result = PyObject_CallFunction((PyObject *)Py_TYPE(&PyCPointer_Type),
"s(O){}", "s(O){}",
...@@ -1818,13 +1820,16 @@ POINTER(PyObject *self, PyObject *cls) ...@@ -1818,13 +1820,16 @@ POINTER(PyObject *self, PyObject *cls)
key = PyLong_FromVoidPtr(result); key = PyLong_FromVoidPtr(result);
} else if (PyType_Check(cls)) { } else if (PyType_Check(cls)) {
typ = (PyTypeObject *)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); sprintf(buf, "LP_%s", typ->tp_name);
result = PyObject_CallFunction((PyObject *)Py_TYPE(&PyCPointer_Type), result = PyObject_CallFunction((PyObject *)Py_TYPE(&PyCPointer_Type),
"s(O){sO}", "s(O){sO}",
buf, buf,
&PyCPointer_Type, &PyCPointer_Type,
"_type_", cls); "_type_", cls);
PyMem_Free(buf);
if (result == NULL) if (result == NULL)
return result; return result;
Py_INCREF(cls); Py_INCREF(cls);
......
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