From 8e9e4d8f95d07b5542d67da0bad9cdac2e88662a Mon Sep 17 00:00:00 2001 From: Thomas Heller Date: Tue, 18 Dec 2007 19:00:59 +0000 Subject: [PATCH] Issue #1642: Fix segfault in ctypes when trying to delete attributes. --- Lib/ctypes/test/test_delattr.py | 21 +++++++++++++++++++++ Misc/NEWS | 2 ++ Modules/_ctypes/_ctypes.c | 16 ++++++++++++++++ Modules/_ctypes/cfield.c | 5 +++++ 4 files changed, 44 insertions(+) create mode 100644 Lib/ctypes/test/test_delattr.py diff --git a/Lib/ctypes/test/test_delattr.py b/Lib/ctypes/test/test_delattr.py new file mode 100644 index 00000000000..0f4d58691b5 --- /dev/null +++ b/Lib/ctypes/test/test_delattr.py @@ -0,0 +1,21 @@ +import unittest +from ctypes import * + +class X(Structure): + _fields_ = [("foo", c_int)] + +class TestCase(unittest.TestCase): + def test_simple(self): + self.assertRaises(TypeError, + delattr, c_int(42), "value") + + def test_chararray(self): + self.assertRaises(TypeError, + delattr, (c_char * 5)(), "value") + + def test_struct(self): + self.assertRaises(TypeError, + delattr, X(), "foo") + +if __name__ == "__main__": + unittest.main() diff --git a/Misc/NEWS b/Misc/NEWS index c87c3c8c0d6..0b24d7f991b 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -49,6 +49,8 @@ Core and builtins Library ------- +- Issue #1642: Fix segfault in ctypes when trying to delete attributes. + - os.access now returns True on Windows for any existing directory. - Issue #1531: tarfile.py: Read fileobj from the current offset, do not diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c index 4dd35c233f8..fa0552c6eee 100644 --- a/Modules/_ctypes/_ctypes.c +++ b/Modules/_ctypes/_ctypes.c @@ -791,6 +791,12 @@ CharArray_set_value(CDataObject *self, PyObject *value) char *ptr; int size; + if (value == NULL) { + PyErr_SetString(PyExc_TypeError, + "can't delete attribute"); + return -1; + } + if (PyUnicode_Check(value)) { value = PyUnicode_AsEncodedString(value, conversion_mode_encoding, @@ -846,6 +852,11 @@ WCharArray_set_value(CDataObject *self, PyObject *value) { int result = 0; + if (value == NULL) { + PyErr_SetString(PyExc_TypeError, + "can't delete attribute"); + return -1; + } if (PyString_Check(value)) { value = PyUnicode_FromEncodedObject(value, conversion_mode_encoding, @@ -3969,6 +3980,11 @@ Simple_set_value(CDataObject *self, PyObject *value) PyObject *result; StgDictObject *dict = PyObject_stgdict((PyObject *)self); + if (value == NULL) { + PyErr_SetString(PyExc_TypeError, + "can't delete attribute"); + return -1; + } assert(dict); /* Cannot be NULL for CDataObject instances */ assert(dict->setfunc); result = dict->setfunc(self->b_ptr, value, dict->size); diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c index 8cb1f193437..0fd82bc02fb 100644 --- a/Modules/_ctypes/cfield.c +++ b/Modules/_ctypes/cfield.c @@ -199,6 +199,11 @@ CField_set(CFieldObject *self, PyObject *inst, PyObject *value) assert(CDataObject_Check(inst)); dst = (CDataObject *)inst; ptr = dst->b_ptr + self->offset; + if (value == NULL) { + PyErr_SetString(PyExc_TypeError, + "can't delete attribute"); + return -1; + } return CData_set(inst, self->proto, self->setfunc, value, self->index, self->size, ptr); }