From ad349a190e923b32e7ef43ddafffde93df75051a Mon Sep 17 00:00:00 2001 From: Meador Inge Date: Mon, 3 Oct 2011 21:34:04 -0500 Subject: Issue #12881: ctypes: Fix segfault with large structure field names. --- Lib/ctypes/test/test_structures.py | 12 ++++++++++++ Misc/NEWS | 2 ++ Modules/_ctypes/stgdict.c | 8 +++++++- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/Lib/ctypes/test/test_structures.py b/Lib/ctypes/test/test_structures.py index a84bae0..1bde101 100644 --- a/Lib/ctypes/test/test_structures.py +++ b/Lib/ctypes/test/test_structures.py @@ -332,6 +332,18 @@ class StructureTestCase(unittest.TestCase): else: self.assertEqual(msg, "(Phone) exceptions.TypeError: too many initializers") + def test_huge_field_name(self): + # issue12881: segfault with large structure field names + def create_class(length): + class S(Structure): + _fields_ = [('x' * length, c_int)] + + for length in [10 ** i for i in range(0, 8)]: + try: + create_class(length) + except MemoryError: + # MemoryErrors are OK, we just don't want to segfault + pass def get_except(self, func, *args): try: diff --git a/Misc/NEWS b/Misc/NEWS index ddcbde1..68d32a6 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -210,6 +210,8 @@ Library Extension Modules ----------------- +- Issue #12881: ctypes: Fix segfault with large structure field names. + - Issue #13013: ctypes: Fix a reference leak in PyCArrayType_from_ctype. Thanks to Suman Saha for finding the bug and providing a patch. diff --git a/Modules/_ctypes/stgdict.c b/Modules/_ctypes/stgdict.c index 4d4ecc4..773233f 100644 --- a/Modules/_ctypes/stgdict.c +++ b/Modules/_ctypes/stgdict.c @@ -508,13 +508,19 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct } len = strlen(fieldname) + strlen(fieldfmt); - buf = alloca(len + 2 + 1); + buf = PyMem_Malloc(len + 2 + 1); + if (buf == NULL) { + Py_DECREF(pair); + PyErr_NoMemory(); + return -1; + } sprintf(buf, "%s:%s:", fieldfmt, fieldname); ptr = stgdict->format; stgdict->format = _ctypes_alloc_format_string(stgdict->format, buf); PyMem_Free(ptr); + PyMem_Free(buf); if (stgdict->format == NULL) { Py_DECREF(pair); -- cgit v0.12