Issue #12881: ctypes: Fix segfault with large structure field names.

This commit is contained in:
Meador Inge 2011-10-03 21:34:04 -05:00
parent 83cc512a01
commit ad349a190e
3 changed files with 21 additions and 1 deletions

View File

@ -332,6 +332,18 @@ class StructureTestCase(unittest.TestCase):
else: else:
self.assertEqual(msg, "(Phone) exceptions.TypeError: too many initializers") 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): def get_except(self, func, *args):
try: try:

View File

@ -210,6 +210,8 @@ Library
Extension Modules Extension Modules
----------------- -----------------
- Issue #12881: ctypes: Fix segfault with large structure field names.
- Issue #13013: ctypes: Fix a reference leak in PyCArrayType_from_ctype. - Issue #13013: ctypes: Fix a reference leak in PyCArrayType_from_ctype.
Thanks to Suman Saha for finding the bug and providing a patch. Thanks to Suman Saha for finding the bug and providing a patch.

View File

@ -508,13 +508,19 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct
} }
len = strlen(fieldname) + strlen(fieldfmt); 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); sprintf(buf, "%s:%s:", fieldfmt, fieldname);
ptr = stgdict->format; ptr = stgdict->format;
stgdict->format = _ctypes_alloc_format_string(stgdict->format, buf); stgdict->format = _ctypes_alloc_format_string(stgdict->format, buf);
PyMem_Free(ptr); PyMem_Free(ptr);
PyMem_Free(buf);
if (stgdict->format == NULL) { if (stgdict->format == NULL) {
Py_DECREF(pair); Py_DECREF(pair);