summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMeador Inge <meadori@gmail.com>2011-10-04 02:44:22 (GMT)
committerMeador Inge <meadori@gmail.com>2011-10-04 02:44:22 (GMT)
commit1efb33a6823b94739e59d6e2fe92e8e703a7fc7d (patch)
tree86f8d676cb9b8ca47f20e63f8533de58b8e0c28c
parent5d0de3fbaa6d3c6ba9c1c510a943df249bdd61e7 (diff)
downloadcpython-1efb33a6823b94739e59d6e2fe92e8e703a7fc7d.zip
cpython-1efb33a6823b94739e59d6e2fe92e8e703a7fc7d.tar.gz
cpython-1efb33a6823b94739e59d6e2fe92e8e703a7fc7d.tar.bz2
Issue #12881: ctypes: Fix segfault with large structure field names.
-rw-r--r--Lib/ctypes/test/test_structures.py12
-rw-r--r--Misc/NEWS2
-rw-r--r--Modules/_ctypes/stgdict.c8
3 files changed, 21 insertions, 1 deletions
diff --git a/Lib/ctypes/test/test_structures.py b/Lib/ctypes/test/test_structures.py
index e4530d5..b6d8b01 100644
--- a/Lib/ctypes/test/test_structures.py
+++ b/Lib/ctypes/test/test_structures.py
@@ -326,6 +326,18 @@ class StructureTestCase(unittest.TestCase):
else:
self.assertEqual(msg, "(Phone) 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 42627a2..aebd899 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -87,6 +87,8 @@ Tests
Extension Modules
-----------------
+- Issue #12881: ctypes: Fix segfault with large structure field names.
+
- Issue #13058: ossaudiodev: fix a file descriptor leak on error. Patch by
Thomas Jarosch.
diff --git a/Modules/_ctypes/stgdict.c b/Modules/_ctypes/stgdict.c
index 14dc16f..262d0b4 100644
--- a/Modules/_ctypes/stgdict.c
+++ b/Modules/_ctypes/stgdict.c
@@ -496,13 +496,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);