diff options
author | Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | 2017-09-25 08:49:08 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2017-09-25 08:49:08 (GMT) |
commit | a6bddb8e4397df30926eb1ade6420a2277174227 (patch) | |
tree | 208f61f1f1eac173aa9947944ac2243071ec05a8 | |
parent | e2a30cd35b95dad55aea10347655f246348d1951 (diff) | |
download | cpython-a6bddb8e4397df30926eb1ade6420a2277174227.zip cpython-a6bddb8e4397df30926eb1ade6420a2277174227.tar.gz cpython-a6bddb8e4397df30926eb1ade6420a2277174227.tar.bz2 |
[3.6] bpo-31311: Fix a SystemError and a crash in ctypes._CData.__setstate__(), in case of a bad __dict__. (GH-3254) (#3743)
(cherry picked from commit 57c2561c8c5663aef55b00e3f29cba575ff36ccd)
-rw-r--r-- | Lib/ctypes/test/test_parameters.py | 21 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Core and Builtins/2017-08-31-17-52-56.bpo-31311.bNE2l-.rst | 2 | ||||
-rw-r--r-- | Modules/_ctypes/_ctypes.c | 10 |
3 files changed, 33 insertions, 0 deletions
diff --git a/Lib/ctypes/test/test_parameters.py b/Lib/ctypes/test/test_parameters.py index 363f586..a61f1c7 100644 --- a/Lib/ctypes/test/test_parameters.py +++ b/Lib/ctypes/test/test_parameters.py @@ -1,5 +1,6 @@ import unittest from ctypes.test import need_symbol +import test.support class SimpleTypesTestCase(unittest.TestCase): @@ -170,6 +171,26 @@ class SimpleTypesTestCase(unittest.TestCase): self.assertRaises(ArgumentError, func, 99) + @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__': diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-08-31-17-52-56.bpo-31311.bNE2l-.rst b/Misc/NEWS.d/next/Core and Builtins/2017-08-31-17-52-56.bpo-31311.bNE2l-.rst new file mode 100644 index 0000000..db51cd2 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2017-08-31-17-52-56.bpo-31311.bNE2l-.rst @@ -0,0 +1,2 @@ +Fix a crash in the ``__setstate__()`` method of `ctypes._CData`, in case of +a bad ``__dict__``. Patch by Oren Milman. diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 1ced630..27f6dd4 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -2663,6 +2663,16 @@ PyCData_setstate(PyObject *myself, PyObject *args) len = self->b_size; memmove(self->b_ptr, data, len); 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); Py_DECREF(mydict); if (res == -1) |