]> granicus.if.org Git - python/commitdiff
#13096: Fix segfault in CTypes POINTER handling of large values.
authorR David Murray <rdmurray@bitdance.com>
Sun, 12 Oct 2014 18:26:30 +0000 (14:26 -0400)
committerR David Murray <rdmurray@bitdance.com>
Sun, 12 Oct 2014 18:26:30 +0000 (14:26 -0400)
Patch by Meador Inge.

Lib/ctypes/test/test_pointers.py
Misc/NEWS
Modules/_ctypes/callproc.c

index 95311586f23a60d54a971ad5353292fb4736ccd7..3e7479195c45499da0f61d81f1ea645e6be77eb0 100644 (file)
@@ -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, long,
                 int, long, long, long, 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()
index 90966f25dfc5603d42649f47e3e836e9dd5563ac..6ff5fe52aaad815b8581451df8894d48235696b4 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -37,6 +37,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.
 
index 6642dc3f4c0ecc04192ad6e01cb3ee54babd4210..19f59e0c9e50249490b04149cfea27be09ab2dd0 100644 (file)
@@ -1807,7 +1807,9 @@ POINTER(PyObject *self, PyObject *cls)
         return result;
     }
     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));
         result = PyObject_CallFunction((PyObject *)Py_TYPE(&PyCPointer_Type),
                                        "s(O){}",
@@ -1818,13 +1820,16 @@ POINTER(PyObject *self, PyObject *cls)
         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);