Commit 81691b05 authored by Serhiy Storchaka's avatar Serhiy Storchaka Committed by GitHub

[2.7] bpo-31311: Fix a SystemError and a crash in...

[2.7] bpo-31311: Fix a SystemError and a crash in ctypes._CData.__setstate__(), in case of a bad __dict__. (GH-3254). (#3781)

(cherry picked from commit 57c2561c)
parent 4954b8dc
import unittest, sys
from ctypes.test import need_symbol
import test.support
class SimpleTypesTestCase(unittest.TestCase):
......@@ -175,6 +176,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__':
......
Fix a crash in the ``__setstate__()`` method of `ctypes._CData`, in case of
a bad ``__dict__``. Patch by Oren Milman.
......@@ -2786,6 +2786,16 @@ PyCData_setstate(PyObject *_self, PyObject *args)
len = self->b_size;
memmove(self->b_ptr, data, len);
mydict = PyObject_GetAttrString(_self, "__dict__");
if (mydict == NULL) {
return NULL;
}
if (!PyDict_Check(mydict)) {
PyErr_Format(PyExc_TypeError,
"%.200s.__dict__ must be a dictionary, not %.200s",
Py_TYPE(_self)->tp_name, Py_TYPE(mydict)->tp_name);
Py_DECREF(mydict);
return NULL;
}
res = PyDict_Update(mydict, dict);
Py_DECREF(mydict);
if (res == -1)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment