diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2018-12-05 14:44:14 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-12-05 14:44:14 (GMT) |
commit | 398bd27967690f2c1a8cbf8d47a5613edd9cfb2a (patch) | |
tree | 0725889bed97f46e4adf5aa47bc5787dc73eb6c9 /Modules/_ctypes/stgdict.c | |
parent | 476b113ed8531b9fbb0bd023a05eb3af21996600 (diff) | |
download | cpython-398bd27967690f2c1a8cbf8d47a5613edd9cfb2a.zip cpython-398bd27967690f2c1a8cbf8d47a5613edd9cfb2a.tar.gz cpython-398bd27967690f2c1a8cbf8d47a5613edd9cfb2a.tar.bz2 |
bpo-32787: Better error handling in ctypes. (#3727)
* bpo-31572: Get rid of PyObject_HasAttrString() in ctypes.
* Fix error handling for _pack_.
* Don't silence errors when look up in a dict.
* Use _PyObject_LookupAttrId().
* More changes.
Diffstat (limited to 'Modules/_ctypes/stgdict.c')
-rw-r--r-- | Modules/_ctypes/stgdict.c | 81 |
1 files changed, 57 insertions, 24 deletions
diff --git a/Modules/_ctypes/stgdict.c b/Modules/_ctypes/stgdict.c index 25656ff..3f8a031 100644 --- a/Modules/_ctypes/stgdict.c +++ b/Modules/_ctypes/stgdict.c @@ -281,13 +281,15 @@ MakeFields(PyObject *type, CFieldObject *descr, static int MakeAnonFields(PyObject *type) { + _Py_IDENTIFIER(_anonymous_); PyObject *anon; PyObject *anon_names; Py_ssize_t i; - anon = PyObject_GetAttrString(type, "_anonymous_"); + if (_PyObject_LookupAttrId(type, &PyId__anonymous_, &anon) < 0) { + return -1; + } if (anon == NULL) { - PyErr_Clear(); return 0; } anon_names = PySequence_Fast(anon, "_anonymous_ must be a sequence"); @@ -335,13 +337,17 @@ MakeAnonFields(PyObject *type) int PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct) { + _Py_IDENTIFIER(_swappedbytes_); + _Py_IDENTIFIER(_use_broken_old_ctypes_structure_semantics_); + _Py_IDENTIFIER(_pack_); StgDictObject *stgdict, *basedict; Py_ssize_t len, offset, size, align, i; Py_ssize_t union_size, total_align; Py_ssize_t field_size = 0; int bitofs; - PyObject *isPacked; - int pack = 0; + PyObject *tmp; + int isPacked; + int pack; Py_ssize_t ffi_ofs; int big_endian; @@ -356,32 +362,59 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct if (fields == NULL) return 0; -#ifdef WORDS_BIGENDIAN - big_endian = PyObject_HasAttrString(type, "_swappedbytes_") ? 0 : 1; -#else - big_endian = PyObject_HasAttrString(type, "_swappedbytes_") ? 1 : 0; -#endif + if (_PyObject_LookupAttrId(type, &PyId__swappedbytes_, &tmp) < 0) { + return -1; + } + if (tmp) { + Py_DECREF(tmp); + big_endian = !PY_BIG_ENDIAN; + } + else { + big_endian = PY_BIG_ENDIAN; + } - use_broken_old_ctypes_semantics = \ - PyObject_HasAttrString(type, "_use_broken_old_ctypes_structure_semantics_"); + if (_PyObject_LookupAttrId(type, + &PyId__use_broken_old_ctypes_structure_semantics_, &tmp) < 0) + { + return -1; + } + if (tmp) { + Py_DECREF(tmp); + use_broken_old_ctypes_semantics = 1; + } + else { + use_broken_old_ctypes_semantics = 0; + } - isPacked = PyObject_GetAttrString(type, "_pack_"); - if (isPacked) { - pack = _PyLong_AsInt(isPacked); - if (pack < 0 || PyErr_Occurred()) { - Py_XDECREF(isPacked); - PyErr_SetString(PyExc_ValueError, - "_pack_ must be a non-negative integer"); + if (_PyObject_LookupAttrId(type, &PyId__pack_, &tmp) < 0) { + return -1; + } + if (tmp) { + isPacked = 1; + pack = _PyLong_AsInt(tmp); + Py_DECREF(tmp); + if (pack < 0) { + if (!PyErr_Occurred() || + PyErr_ExceptionMatches(PyExc_TypeError) || + PyErr_ExceptionMatches(PyExc_OverflowError)) + { + PyErr_SetString(PyExc_ValueError, + "_pack_ must be a non-negative integer"); + } return -1; } - Py_DECREF(isPacked); - } else - PyErr_Clear(); + } + else { + isPacked = 0; + pack = 0; + } - len = PySequence_Length(fields); + len = PySequence_Size(fields); if (len == -1) { - PyErr_SetString(PyExc_TypeError, - "'_fields_' must be a sequence of pairs"); + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + PyErr_SetString(PyExc_TypeError, + "'_fields_' must be a sequence of pairs"); + } return -1; } |