[Python-checkins] cpython (3.4): #13096: Fix segfault in CTypes POINTER handling of large values.

r.david.murray python-checkins at python.org
Sun Oct 12 20:26:59 CEST 2014


https://hg.python.org/cpython/rev/e940bb13d010
changeset:   93004:e940bb13d010
branch:      3.4
parent:      93002:f6f098bdb843
user:        R David Murray <rdmurray at bitdance.com>
date:        Sun Oct 12 13:54:48 2014 -0400
summary:
  #13096: Fix segfault in CTypes POINTER handling of large values.

Patch by Meador Inge.

files:
  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
--- a/Lib/ctypes/test/test_pointers.py
+++ b/Lib/ctypes/test/test_pointers.py
@@ -7,6 +7,8 @@
                  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 @@
             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
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -27,6 +27,9 @@
 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
--- a/Modules/_ctypes/callproc.c
+++ b/Modules/_ctypes/callproc.c
@@ -1672,24 +1672,30 @@
     }
     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);

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list