mirror of
https://github.com/python/cpython.git
synced 2025-12-11 19:40:17 +00:00
bpo-31311: Fix a SystemError and a crash in ctypes._CData.__setstate__(), in case of a bad __dict__. (#3254)
This commit is contained in:
parent
0d4497b9ca
commit
57c2561c8c
3 changed files with 33 additions and 0 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
import unittest
|
import unittest
|
||||||
from ctypes.test import need_symbol
|
from ctypes.test import need_symbol
|
||||||
|
import test.support
|
||||||
|
|
||||||
class SimpleTypesTestCase(unittest.TestCase):
|
class SimpleTypesTestCase(unittest.TestCase):
|
||||||
|
|
||||||
|
|
@ -180,6 +181,26 @@ class SimpleTypesTestCase(unittest.TestCase):
|
||||||
self.assertRaises(TypeError, _Pointer.from_param, 42)
|
self.assertRaises(TypeError, _Pointer.from_param, 42)
|
||||||
self.assertRaises(TypeError, _SimpleCData.from_param, 42)
|
self.assertRaises(TypeError, _SimpleCData.from_param, 42)
|
||||||
|
|
||||||
|
@test.support.cpython_only
|
||||||
|
def test_issue31311(self):
|
||||||
|
# __setstate__ should neither raise a SystemError nor crash in case
|
||||||
|
# of a bad __dict__.
|
||||||
|
from ctypes import Structure
|
||||||
|
|
||||||
|
class BadStruct(Structure):
|
||||||
|
@property
|
||||||
|
def __dict__(self):
|
||||||
|
pass
|
||||||
|
with self.assertRaises(TypeError):
|
||||||
|
BadStruct().__setstate__({}, b'foo')
|
||||||
|
|
||||||
|
class WorseStruct(Structure):
|
||||||
|
@property
|
||||||
|
def __dict__(self):
|
||||||
|
1/0
|
||||||
|
with self.assertRaises(ZeroDivisionError):
|
||||||
|
WorseStruct().__setstate__({}, b'foo')
|
||||||
|
|
||||||
################################################################
|
################################################################
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
Fix a crash in the ``__setstate__()`` method of `ctypes._CData`, in case of
|
||||||
|
a bad ``__dict__``. Patch by Oren Milman.
|
||||||
|
|
@ -2674,6 +2674,16 @@ PyCData_setstate(PyObject *myself, PyObject *args)
|
||||||
len = self->b_size;
|
len = self->b_size;
|
||||||
memmove(self->b_ptr, data, len);
|
memmove(self->b_ptr, data, len);
|
||||||
mydict = PyObject_GetAttrString(myself, "__dict__");
|
mydict = PyObject_GetAttrString(myself, "__dict__");
|
||||||
|
if (mydict == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (!PyDict_Check(mydict)) {
|
||||||
|
PyErr_Format(PyExc_TypeError,
|
||||||
|
"%.200s.__dict__ must be a dictionary, not %.200s",
|
||||||
|
Py_TYPE(myself)->tp_name, Py_TYPE(mydict)->tp_name);
|
||||||
|
Py_DECREF(mydict);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
res = PyDict_Update(mydict, dict);
|
res = PyDict_Update(mydict, dict);
|
||||||
Py_DECREF(mydict);
|
Py_DECREF(mydict);
|
||||||
if (res == -1)
|
if (res == -1)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue