mirror of
https://github.com/python/cpython.git
synced 2025-09-28 19:25:27 +00:00
#13096: Fix segfault in CTypes POINTER handling of large values.
Patch by Meador Inge.
This commit is contained in:
parent
4cfb5bee89
commit
817905b239
3 changed files with 19 additions and 2 deletions
|
@ -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]
|
c_long, c_ulong, c_longlong, c_ulonglong, c_double, c_float]
|
||||||
python_types = [int, int, int, int, int, int,
|
python_types = [int, int, int, int, int, int,
|
||||||
int, int, int, int, float, float]
|
int, int, int, int, float, float]
|
||||||
|
LargeNamedType = type('T' * 2 ** 25, (Structure,), {})
|
||||||
|
large_string = 'T' * 2 ** 25
|
||||||
|
|
||||||
class PointersTestCase(unittest.TestCase):
|
class PointersTestCase(unittest.TestCase):
|
||||||
|
|
||||||
|
@ -188,5 +190,11 @@ class PointersTestCase(unittest.TestCase):
|
||||||
mth = WINFUNCTYPE(None)(42, "name", (), None)
|
mth = WINFUNCTYPE(None)(42, "name", (), None)
|
||||||
self.assertEqual(bool(mth), True)
|
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__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
@ -27,6 +27,9 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #13096: Fixed segfault in CTypes POINTER handling of large
|
||||||
|
values.
|
||||||
|
|
||||||
- Issue #11694: Raise ConversionError in xdrlib as documented. Patch
|
- Issue #11694: Raise ConversionError in xdrlib as documented. Patch
|
||||||
by Filip Gruszczyński and Claudiu Popa.
|
by Filip Gruszczyński and Claudiu Popa.
|
||||||
|
|
||||||
|
|
|
@ -1672,24 +1672,30 @@ POINTER(PyObject *self, PyObject *cls)
|
||||||
}
|
}
|
||||||
if (PyUnicode_CheckExact(cls)) {
|
if (PyUnicode_CheckExact(cls)) {
|
||||||
char *name = _PyUnicode_AsString(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);
|
sprintf(buf, "LP_%s", name);
|
||||||
result = PyObject_CallFunction((PyObject *)Py_TYPE(&PyCPointer_Type),
|
result = PyObject_CallFunction((PyObject *)Py_TYPE(&PyCPointer_Type),
|
||||||
"s(O){}",
|
"s(O){}",
|
||||||
buf,
|
buf,
|
||||||
&PyCPointer_Type);
|
&PyCPointer_Type);
|
||||||
|
PyMem_Free(buf);
|
||||||
if (result == NULL)
|
if (result == NULL)
|
||||||
return result;
|
return result;
|
||||||
key = PyLong_FromVoidPtr(result);
|
key = PyLong_FromVoidPtr(result);
|
||||||
} else if (PyType_Check(cls)) {
|
} else if (PyType_Check(cls)) {
|
||||||
typ = (PyTypeObject *)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);
|
sprintf(buf, "LP_%s", typ->tp_name);
|
||||||
result = PyObject_CallFunction((PyObject *)Py_TYPE(&PyCPointer_Type),
|
result = PyObject_CallFunction((PyObject *)Py_TYPE(&PyCPointer_Type),
|
||||||
"s(O){sO}",
|
"s(O){sO}",
|
||||||
buf,
|
buf,
|
||||||
&PyCPointer_Type,
|
&PyCPointer_Type,
|
||||||
"_type_", cls);
|
"_type_", cls);
|
||||||
|
PyMem_Free(buf);
|
||||||
if (result == NULL)
|
if (result == NULL)
|
||||||
return result;
|
return result;
|
||||||
Py_INCREF(cls);
|
Py_INCREF(cls);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue