8000 new experiment for CreateSwappedType() crash · python/cpython@bc9c8cb · GitHub
[go: up one dir, main page]

Skip to content

Commit bc9c8cb

Browse files
committed
new experiment for CreateSwappedType() crash
1 parent baa1780 commit bc9c8cb

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed

Lib/test/test_ctypes/test_simplesubclasses.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ def test_type_flags(self):
2626
self.assertTrue(_SimpleCData.__flags__ & Py_TPFLAGS_IMMUTABLETYPE)
2727
self.assertFalse(_SimpleCData.__flags__ & Py_TPFLAGS_DISALLOW_INSTANTIATION)
2828

29+
def test_swapped_type_creation(self):
30+
cls = PyCSimpleType.__new__(PyCSimpleType, '', (), {'_type_': 'i'})
31+
PyCSimpleType.__init__(cls)
32+
self.assertEqual(cls.__ctype_le__.__dict__.get('_type_'), 'i')
33+
self.assertEqual(cls.__ctype_be__.__dict__.get('_type_'), 'i')
34+
2935
def test_compare(self):
3036
self.assertEqual(MyInt(3), MyInt(3))
3137
self.assertNotEqual(MyInt(42), MyInt(43))

Modules/_ctypes/_ctypes.c

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1847,6 +1847,42 @@ static PyMethodDef c_void_p_method = { "from_param", c_void_p_from_param, METH_O
18471847
static PyMethodDef c_char_p_method = { "from_param", c_char_p_from_param, METH_O };
18481848
static PyMethodDef c_wchar_p_method = { "from_param", c_wchar_p_from_param, METH_O };
18491849

1850+
// Complete arguments passed to PyCSimpleType_init() and CreateSwappedType()
1851+
static PyObject *
1852+
CreateSwappedType_ready(PyObject *self, PyObject *args)
1853+
{
1854+
PyObject *dict;
1855+
if (!PyTuple_CheckExact(args) || PyTuple_GET_SIZE(args) < 3) {
1856+
dict = PyDict_New();
1857+
}
1858+
else {
1859+
dict = PyDict_Copy(PyTuple_GET_ITEM(args, 2));
1860+
}
1861+
if (!dict) {
1862+
return NULL;
1863+
}
1864+
if (PyDict_Update(dict, ((PyTypeObject *)self)->tp_dict) < 0) {
1865+
Py_DECREF(dict);
1866+
return NULL;
1867+
}
1868+
if (PyDict_DelItem(dict, &_Py_ID(__dict__))) {
1869+
PyErr_Clear();
1870+
}
1871+
if (PyDict_DelItem(dict, &_Py_ID(__weakref__))) {
1872+
PyErr_Clear();
1873+
}
1874+
1875+
PyObject *safe_args = PyTuple_New(3);
1876+
if (!safe_args) {
1877+
Py_DECREF(dict);
1878+
return NULL;
1879+
}
1880+
PyTuple_SET_ITEM(safe_args, 0, PyType_GetName((PyTypeObject *)self));
1881+
PyTuple_SET_ITEM(safe_args, 1, Py_NewRef(((PyTypeObject *)self)->tp_bases));
1882+
PyTuple_SET_ITEM(safe_args, 2, dict);
1883+
return safe_args;
1884+
}
1885+
18501886
static PyObject *CreateSwappedType(PyTypeObject *type, PyObject *args, PyObject *kwds,
18511887
PyObject *proto, struct fielddesc *fmt)
18521888
{
@@ -2088,8 +2124,13 @@ PyCSimpleType_init(PyObject *self, PyObject *args, PyObject *kwds)
20882124
&& fmt->setfunc_swapped
20892125
&& fmt->getfunc_swapped)
20902126
{
2091-
PyObject *swapped = CreateSwappedType(type, args, kwds,
2127+
PyObject *safe_args = CreateSwappedType_ready(self, args);
2128+
if (!safe_args) {
2129+
return -1;
2130+
}
2131+
PyObject *swapped = CreateSwappedType(type, safe_args, kwds,
20922132
proto, fmt);
2133+
Py_DECREF(safe_args);
20932134
StgDictObject *sw_dict;
20942135
if (swapped == NULL) {
20952136
return -1;

0 commit comments

Comments
 (0)
0