Commit 398bd279 authored by Serhiy Storchaka's avatar Serhiy Storchaka Committed by GitHub

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.
parent 476b113e
...@@ -236,7 +236,7 @@ PyObject * ...@@ -236,7 +236,7 @@ PyObject *
PyDict_GetItemProxy(PyObject *dict, PyObject *key) PyDict_GetItemProxy(PyObject *dict, PyObject *key)
{ {
PyObject *result; PyObject *result;
PyObject *item = PyDict_GetItem(dict, key); PyObject *item = PyDict_GetItemWithError(dict, key);
if (item == NULL) if (item == NULL)
return NULL; return NULL;
...@@ -426,6 +426,8 @@ StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isSt ...@@ -426,6 +426,8 @@ StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isSt
PyTypeObject *result; PyTypeObject *result;
PyObject *fields; PyObject *fields;
StgDictObject *dict; StgDictObject *dict;
_Py_IDENTIFIER(_abstract_);
_Py_IDENTIFIER(_fields_);
/* create the new instance (which is a class, /* create the new instance (which is a class,
since we are a metatype!) */ since we are a metatype!) */
...@@ -434,8 +436,12 @@ StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isSt ...@@ -434,8 +436,12 @@ StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isSt
return NULL; return NULL;
/* keep this for bw compatibility */ /* keep this for bw compatibility */
if (PyDict_GetItemString(result->tp_dict, "_abstract_")) if (_PyDict_GetItemIdWithError(result->tp_dict, &PyId__abstract_))
return (PyObject *)result; return (PyObject *)result;
if (PyErr_Occurred()) {
Py_DECREF(result);
return NULL;
}
dict = (StgDictObject *)_PyObject_CallNoArg((PyObject *)&PyCStgDict_Type); dict = (StgDictObject *)_PyObject_CallNoArg((PyObject *)&PyCStgDict_Type);
if (!dict) { if (!dict) {
...@@ -458,8 +464,19 @@ StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isSt ...@@ -458,8 +464,19 @@ StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isSt
dict->paramfunc = StructUnionType_paramfunc; dict->paramfunc = StructUnionType_paramfunc;
fields = PyDict_GetItemString((PyObject *)dict, "_fields_"); fields = _PyDict_GetItemIdWithError((PyObject *)dict, &PyId__fields_);
if (!fields) { if (fields) {
if (_PyObject_SetAttrId((PyObject *)result, &PyId__fields_, fields) < 0) {
Py_DECREF(result);
return NULL;
}
return (PyObject *)result;
}
else if (PyErr_Occurred()) {
Py_DECREF(result);
return NULL;
}
else {
StgDictObject *basedict = PyType_stgdict((PyObject *)result->tp_base); StgDictObject *basedict = PyType_stgdict((PyObject *)result->tp_base);
if (basedict == NULL) if (basedict == NULL)
...@@ -473,12 +490,6 @@ StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isSt ...@@ -473,12 +490,6 @@ StructUnionType_new(PyTypeObject *type, PyObject *args, PyObject *kwds, int isSt
basedict->flags |= DICTFLAG_FINAL; /* set the 'final' flag in the baseclass dict */ basedict->flags |= DICTFLAG_FINAL; /* set the 'final' flag in the baseclass dict */
return (PyObject *)result; return (PyObject *)result;
} }
if (-1 == PyObject_SetAttrString((PyObject *)result, "_fields_", fields)) {
Py_DECREF(result);
return NULL;
}
return (PyObject *)result;
} }
static PyObject * static PyObject *
...@@ -693,6 +704,7 @@ static const char from_param_doc[] = ...@@ -693,6 +704,7 @@ static const char from_param_doc[] =
static PyObject * static PyObject *
CDataType_from_param(PyObject *type, PyObject *value) CDataType_from_param(PyObject *type, PyObject *value)
{ {
_Py_IDENTIFIER(_as_parameter_);
PyObject *as_parameter; PyObject *as_parameter;
int res = PyObject_IsInstance(value, type); int res = PyObject_IsInstance(value, type);
if (res == -1) if (res == -1)
...@@ -726,7 +738,9 @@ CDataType_from_param(PyObject *type, PyObject *value) ...@@ -726,7 +738,9 @@ CDataType_from_param(PyObject *type, PyObject *value)
return NULL; return NULL;
} }
as_parameter = PyObject_GetAttrString(value, "_as_parameter_"); if (_PyObject_LookupAttrId(value, &PyId__as_parameter_, &as_parameter) < 0) {
return NULL;
}
if (as_parameter) { if (as_parameter) {
value = CDataType_from_param(type, as_parameter); value = CDataType_from_param(type, as_parameter);
Py_DECREF(as_parameter); Py_DECREF(as_parameter);
...@@ -961,6 +975,7 @@ PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) ...@@ -961,6 +975,7 @@ PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
StgDictObject *stgdict; StgDictObject *stgdict;
PyObject *proto; PyObject *proto;
PyObject *typedict; PyObject *typedict;
_Py_IDENTIFIER(_type_);
typedict = PyTuple_GetItem(args, 2); typedict = PyTuple_GetItem(args, 2);
if (!typedict) if (!typedict)
...@@ -980,15 +995,15 @@ PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) ...@@ -980,15 +995,15 @@ PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
stgdict->paramfunc = PyCPointerType_paramfunc; stgdict->paramfunc = PyCPointerType_paramfunc;
stgdict->flags |= TYPEFLAG_ISPOINTER; stgdict->flags |= TYPEFLAG_ISPOINTER;
proto = PyDict_GetItemString(typedict, "_type_"); /* Borrowed ref */ proto = _PyDict_GetItemIdWithError(typedict, &PyId__type_); /* Borrowed ref */
if (proto && -1 == PyCPointerType_SetProto(stgdict, proto)) { if (proto) {
StgDictObject *itemdict;
const char *current_format;
if (-1 == PyCPointerType_SetProto(stgdict, proto)) {
Py_DECREF((PyObject *)stgdict); Py_DECREF((PyObject *)stgdict);
return NULL; return NULL;
} }
itemdict = PyType_stgdict(proto);
if (proto) {
StgDictObject *itemdict = PyType_stgdict(proto);
const char *current_format;
/* PyCPointerType_SetProto has verified proto has a stgdict. */ /* PyCPointerType_SetProto has verified proto has a stgdict. */
assert(itemdict); assert(itemdict);
/* If itemdict->format is NULL, then this is a pointer to an /* If itemdict->format is NULL, then this is a pointer to an
...@@ -1009,6 +1024,10 @@ PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) ...@@ -1009,6 +1024,10 @@ PyCPointerType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
return NULL; return NULL;
} }
} }
else if (PyErr_Occurred()) {
Py_DECREF((PyObject *)stgdict);
return NULL;
}
/* create the new instance (which is a class, /* create the new instance (which is a class,
since we are a metatype!) */ since we are a metatype!) */
...@@ -1034,6 +1053,7 @@ static PyObject * ...@@ -1034,6 +1053,7 @@ static PyObject *
PyCPointerType_set_type(PyTypeObject *self, PyObject *type) PyCPointerType_set_type(PyTypeObject *self, PyObject *type)
{ {
StgDictObject *dict; StgDictObject *dict;
_Py_IDENTIFIER(_type_);
dict = PyType_stgdict((PyObject *)self); dict = PyType_stgdict((PyObject *)self);
if (!dict) { if (!dict) {
...@@ -1045,7 +1065,7 @@ PyCPointerType_set_type(PyTypeObject *self, PyObject *type) ...@@ -1045,7 +1065,7 @@ PyCPointerType_set_type(PyTypeObject *self, PyObject *type)
if (-1 == PyCPointerType_SetProto(dict, type)) if (-1 == PyCPointerType_SetProto(dict, type))
return NULL; return NULL;
if (-1 == PyDict_SetItemString((PyObject *)dict, "_type_", type)) if (-1 == _PyDict_SetItemId((PyObject *)dict, &PyId__type_, type))
return NULL; return NULL;
Py_RETURN_NONE; Py_RETURN_NONE;
...@@ -1386,6 +1406,8 @@ PyCArrayType_paramfunc(CDataObject *self) ...@@ -1386,6 +1406,8 @@ PyCArrayType_paramfunc(CDataObject *self)
static PyObject * static PyObject *
PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{ {
_Py_IDENTIFIER(_length_);
_Py_IDENTIFIER(_type_);
PyTypeObject *result; PyTypeObject *result;
StgDictObject *stgdict; StgDictObject *stgdict;
StgDictObject *itemdict; StgDictObject *itemdict;
...@@ -1404,12 +1426,12 @@ PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) ...@@ -1404,12 +1426,12 @@ PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
stgdict = NULL; stgdict = NULL;
type_attr = NULL; type_attr = NULL;
length_attr = PyObject_GetAttrString((PyObject *)result, "_length_"); if (_PyObject_LookupAttrId((PyObject *)result, &PyId__length_, &length_attr) < 0) {
goto error;
}
if (!length_attr) { if (!length_attr) {
if (PyErr_ExceptionMatches(PyExc_AttributeError)) {
PyErr_SetString(PyExc_AttributeError, PyErr_SetString(PyExc_AttributeError,
"class must define a '_length_' attribute"); "class must define a '_length_' attribute");
}
goto error; goto error;
} }
...@@ -1437,7 +1459,9 @@ PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) ...@@ -1437,7 +1459,9 @@ PyCArrayType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
goto error; goto error;
} }
type_attr = PyObject_GetAttrString((PyObject *)result, "_type_"); if (_PyObject_LookupAttrId((PyObject *)result, &PyId__type_, &type_attr) < 0) {
goto error;
}
if (!type_attr) { if (!type_attr) {
PyErr_SetString(PyExc_AttributeError, PyErr_SetString(PyExc_AttributeError,
"class must define a '_type_' attribute"); "class must define a '_type_' attribute");
...@@ -1580,6 +1604,7 @@ static const char SIMPLE_TYPE_CHARS[] = "cbBhHiIlLdfuzZqQPXOv?g"; ...@@ -1580,6 +1604,7 @@ static const char SIMPLE_TYPE_CHARS[] = "cbBhHiIlLdfuzZqQPXOv?g";
static PyObject * static PyObject *
c_wchar_p_from_param(PyObject *type, PyObject *value) c_wchar_p_from_param(PyObject *type, PyObject *value)
{ {
_Py_IDENTIFIER(_as_parameter_);
PyObject *as_parameter; PyObject *as_parameter;
int res; int res;
if (value == Py_None) { if (value == Py_None) {
...@@ -1629,7 +1654,9 @@ c_wchar_p_from_param(PyObject *type, PyObject *value) ...@@ -1629,7 +1654,9 @@ c_wchar_p_from_param(PyObject *type, PyObject *value)
} }
} }
as_parameter = PyObject_GetAttrString(value, "_as_parameter_"); if (_PyObject_LookupAttrId(value, &PyId__as_parameter_, &as_parameter) < 0) {
return NULL;
}
if (as_parameter) { if (as_parameter) {
value = c_wchar_p_from_param(type, as_parameter); value = c_wchar_p_from_param(type, as_parameter);
Py_DECREF(as_parameter); Py_DECREF(as_parameter);
...@@ -1644,6 +1671,7 @@ c_wchar_p_from_param(PyObject *type, PyObject *value) ...@@ -1644,6 +1671,7 @@ c_wchar_p_from_param(PyObject *type, PyObject *value)
static PyObject * static PyObject *
c_char_p_from_param(PyObject *type, PyObject *value) c_char_p_from_param(PyObject *type, PyObject *value)
{ {
_Py_IDENTIFIER(_as_parameter_);
PyObject *as_parameter; PyObject *as_parameter;
int res; int res;
if (value == Py_None) { if (value == Py_None) {
...@@ -1693,7 +1721,9 @@ c_char_p_from_param(PyObject *type, PyObject *value) ...@@ -1693,7 +1721,9 @@ c_char_p_from_param(PyObject *type, PyObject *value)
} }
} }
as_parameter = PyObject_GetAttrString(value, "_as_parameter_"); if (_PyObject_LookupAttrId(value, &PyId__as_parameter_, &as_parameter) < 0) {
return NULL;
}
if (as_parameter) { if (as_parameter) {
value = c_char_p_from_param(type, as_parameter); value = c_char_p_from_param(type, as_parameter);
Py_DECREF(as_parameter); Py_DECREF(as_parameter);
...@@ -1708,6 +1738,7 @@ c_char_p_from_param(PyObject *type, PyObject *value) ...@@ -1708,6 +1738,7 @@ c_char_p_from_param(PyObject *type, PyObject *value)
static PyObject * static PyObject *
c_void_p_from_param(PyObject *type, PyObject *value) c_void_p_from_param(PyObject *type, PyObject *value)
{ {
_Py_IDENTIFIER(_as_parameter_);
StgDictObject *stgd; StgDictObject *stgd;
PyObject *as_parameter; PyObject *as_parameter;
int res; int res;
...@@ -1829,7 +1860,9 @@ c_void_p_from_param(PyObject *type, PyObject *value) ...@@ -1829,7 +1860,9 @@ c_void_p_from_param(PyObject *type, PyObject *value)
} }
} }
as_parameter = PyObject_GetAttrString(value, "_as_parameter_"); if (_PyObject_LookupAttrId(value, &PyId__as_parameter_, &as_parameter) < 0) {
return NULL;
}
if (as_parameter) { if (as_parameter) {
value = c_void_p_from_param(type, as_parameter); value = c_void_p_from_param(type, as_parameter);
Py_DECREF(as_parameter); Py_DECREF(as_parameter);
...@@ -1946,6 +1979,7 @@ PyCSimpleType_paramfunc(CDataObject *self) ...@@ -1946,6 +1979,7 @@ PyCSimpleType_paramfunc(CDataObject *self)
static PyObject * static PyObject *
PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{ {
_Py_IDENTIFIER(_type_);
PyTypeObject *result; PyTypeObject *result;
StgDictObject *stgdict; StgDictObject *stgdict;
PyObject *proto; PyObject *proto;
...@@ -1960,13 +1994,15 @@ PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) ...@@ -1960,13 +1994,15 @@ PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
if (result == NULL) if (result == NULL)
return NULL; return NULL;
proto = PyObject_GetAttrString((PyObject *)result, "_type_"); /* new ref */ if (_PyObject_LookupAttrId((PyObject *)result, &PyId__type_, &proto) < 0) {
return NULL;
}
if (!proto) { if (!proto) {
PyErr_SetString(PyExc_AttributeError, PyErr_SetString(PyExc_AttributeError,
"class must define a '_type_' attribute"); "class must define a '_type_' attribute");
error: error:
Py_XDECREF(proto); Py_XDECREF(proto);
Py_XDECREF(result); Py_DECREF(result);
return NULL; return NULL;
} }
if (PyUnicode_Check(proto)) { if (PyUnicode_Check(proto)) {
...@@ -2128,6 +2164,7 @@ PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds) ...@@ -2128,6 +2164,7 @@ PyCSimpleType_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
static PyObject * static PyObject *
PyCSimpleType_from_param(PyObject *type, PyObject *value) PyCSimpleType_from_param(PyObject *type, PyObject *value)
{ {
_Py_IDENTIFIER(_as_parameter_);
StgDictObject *dict; StgDictObject *dict;
const char *fmt; const char *fmt;
PyCArgObject *parg; PyCArgObject *parg;
...@@ -2171,7 +2208,9 @@ PyCSimpleType_from_param(PyObject *type, PyObject *value) ...@@ -2171,7 +2208,9 @@ PyCSimpleType_from_param(PyObject *type, PyObject *value)
PyErr_Clear(); PyErr_Clear();
Py_DECREF(parg); Py_DECREF(parg);
as_parameter = PyObject_GetAttrString(value, "_as_parameter_"); if (_PyObject_LookupAttrId(value, &PyId__as_parameter_, &as_parameter) < 0) {
return NULL;
}
if (as_parameter) { if (as_parameter) {
if (Py_EnterRecursiveCall("while processing _as_parameter_")) { if (Py_EnterRecursiveCall("while processing _as_parameter_")) {
Py_DECREF(as_parameter); Py_DECREF(as_parameter);
...@@ -2246,6 +2285,7 @@ PyTypeObject PyCSimpleType_Type = { ...@@ -2246,6 +2285,7 @@ PyTypeObject PyCSimpleType_Type = {
static PyObject * static PyObject *
converters_from_argtypes(PyObject *ob) converters_from_argtypes(PyObject *ob)
{ {
_Py_IDENTIFIER(from_param);
PyObject *converters; PyObject *converters;
Py_ssize_t i; Py_ssize_t i;
Py_ssize_t nArgs; Py_ssize_t nArgs;
...@@ -2270,22 +2310,22 @@ converters_from_argtypes(PyObject *ob) ...@@ -2270,22 +2310,22 @@ converters_from_argtypes(PyObject *ob)
*/ */
for (i = 0; i < nArgs; ++i) { for (i = 0; i < nArgs; ++i) {
PyObject *cnv;
PyObject *tp = PyTuple_GET_ITEM(ob, i); PyObject *tp = PyTuple_GET_ITEM(ob, i);
PyObject *cnv = PyObject_GetAttrString(tp, "from_param"); if (_PyObject_LookupAttrId(tp, &PyId_from_param, &cnv) <= 0) {
if (!cnv) Py_DECREF(converters);
goto argtypes_error_1;
PyTuple_SET_ITEM(converters, i, cnv);
}
Py_DECREF(ob);
return converters;
argtypes_error_1:
Py_XDECREF(converters);
Py_DECREF(ob); Py_DECREF(ob);
if (!PyErr_Occurred()) {
PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
"item %zd in _argtypes_ has no from_param method", "item %zd in _argtypes_ has no from_param method",
i+1); i+1);
}
return NULL; return NULL;
}
PyTuple_SET_ITEM(converters, i, cnv);
}
Py_DECREF(ob);
return converters;
} }
static int static int
...@@ -2293,6 +2333,10 @@ make_funcptrtype_dict(StgDictObject *stgdict) ...@@ -2293,6 +2333,10 @@ make_funcptrtype_dict(StgDictObject *stgdict)
{ {
PyObject *ob; PyObject *ob;
PyObject *converters = NULL; PyObject *converters = NULL;
_Py_IDENTIFIER(_flags_);
_Py_IDENTIFIER(_argtypes_);
_Py_IDENTIFIER(_restype_);
_Py_IDENTIFIER(_check_retval_);
stgdict->align = _ctypes_get_fielddesc("P")->pffi_type->alignment; stgdict->align = _ctypes_get_fielddesc("P")->pffi_type->alignment;
stgdict->length = 1; stgdict->length = 1;
...@@ -2301,26 +2345,31 @@ make_funcptrtype_dict(StgDictObject *stgdict) ...@@ -2301,26 +2345,31 @@ make_funcptrtype_dict(StgDictObject *stgdict)
stgdict->getfunc = NULL; stgdict->getfunc = NULL;
stgdict->ffi_type_pointer = ffi_type_pointer; stgdict->ffi_type_pointer = ffi_type_pointer;
ob = PyDict_GetItemString((PyObject *)stgdict, "_flags_"); ob = _PyDict_GetItemIdWithError((PyObject *)stgdict, &PyId__flags_);
if (!ob || !PyLong_Check(ob)) { if (!ob || !PyLong_Check(ob)) {
if (!PyErr_Occurred()) {
PyErr_SetString(PyExc_TypeError, PyErr_SetString(PyExc_TypeError,
"class must define _flags_ which must be an integer"); "class must define _flags_ which must be an integer");
}
return -1; return -1;
} }
stgdict->flags = PyLong_AS_LONG(ob) | TYPEFLAG_ISPOINTER; stgdict->flags = PyLong_AsUnsignedLongMask(ob) | TYPEFLAG_ISPOINTER;
/* _argtypes_ is optional... */ /* _argtypes_ is optional... */
ob = PyDict_GetItemString((PyObject *)stgdict, "_argtypes_"); ob = _PyDict_GetItemIdWithError((PyObject *)stgdict, &PyId__argtypes_);
if (ob) { if (ob) {
converters = converters_from_argtypes(ob); converters = converters_from_argtypes(ob);
if (!converters) if (!converters)
goto error; return -1;
Py_INCREF(ob); Py_INCREF(ob);
stgdict->argtypes = ob; stgdict->argtypes = ob;
stgdict->converters = converters; stgdict->converters = converters;
} }
else if (PyErr_Occurred()) {
return -1;
}
ob = PyDict_GetItemString((PyObject *)stgdict, "_restype_"); ob = _PyDict_GetItemIdWithError((PyObject *)stgdict, &PyId__restype_);
if (ob) { if (ob) {
if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) { if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) {
PyErr_SetString(PyExc_TypeError, PyErr_SetString(PyExc_TypeError,
...@@ -2329,12 +2378,17 @@ make_funcptrtype_dict(StgDictObject *stgdict) ...@@ -2329,12 +2378,17 @@ make_funcptrtype_dict(StgDictObject *stgdict)
} }
Py_INCREF(ob); Py_INCREF(ob);
stgdict->restype = ob; stgdict->restype = ob;
stgdict->checker = PyObject_GetAttrString(ob, "_check_retval_"); if (_PyObject_LookupAttrId(ob, &PyId__check_retval_,
if (stgdict->checker == NULL) &stgdict->checker) < 0)
PyErr_Clear(); {
return -1;
}
}
else if (PyErr_Occurred()) {
return -1;
} }
/* XXX later, maybe. /* XXX later, maybe.
ob = PyDict_GetItemString((PyObject *)stgdict, "_errcheck_"); ob = _PyDict_GetItemIdWithError((PyObject *)stgdict, &PyId__errcheck_);
if (ob) { if (ob) {
if (!PyCallable_Check(ob)) { if (!PyCallable_Check(ob)) {
PyErr_SetString(PyExc_TypeError, PyErr_SetString(PyExc_TypeError,
...@@ -2344,13 +2398,11 @@ make_funcptrtype_dict(StgDictObject *stgdict) ...@@ -2344,13 +2398,11 @@ make_funcptrtype_dict(StgDictObject *stgdict)
Py_INCREF(ob); Py_INCREF(ob);
stgdict->errcheck = ob; stgdict->errcheck = ob;
} }
else if (PyErr_Occurred()) {
return -1;
}
*/ */
return 0; return 0;
error:
Py_XDECREF(converters);
return -1;
} }
static PyCArgObject * static PyCArgObject *
...@@ -3085,9 +3137,13 @@ PyCFuncPtr_get_errcheck(PyCFuncPtrObject *self, void *Py_UNUSED(ignored)) ...@@ -3085,9 +3137,13 @@ PyCFuncPtr_get_errcheck(PyCFuncPtrObject *self, void *Py_UNUSED(ignored))
static int static int
PyCFuncPtr_set_restype(PyCFuncPtrObject *self, PyObject *ob, void *Py_UNUSED(ignored)) PyCFuncPtr_set_restype(PyCFuncPtrObject *self, PyObject *ob, void *Py_UNUSED(ignored))
{ {
_Py_IDENTIFIER(_check_retval_);
PyObject *checker, *oldchecker;
if (ob == NULL) { if (ob == NULL) {
oldchecker = self->checker;
self->checker = NULL;
Py_CLEAR(self->restype); Py_CLEAR(self->restype);
Py_CLEAR(self->checker); Py_XDECREF(oldchecker);
return 0; return 0;
} }
if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) { if (ob != Py_None && !PyType_stgdict(ob) && !PyCallable_Check(ob)) {
...@@ -3095,11 +3151,14 @@ PyCFuncPtr_set_restype(PyCFuncPtrObject *self, PyObject *ob, void *Py_UNUSED(ign ...@@ -3095,11 +3151,14 @@ PyCFuncPtr_set_restype(PyCFuncPtrObject *self, PyObject *ob, void *Py_UNUSED(ign
"restype must be a type, a callable, or None"); "restype must be a type, a callable, or None");
return -1; return -1;
} }
if (_PyObject_LookupAttrId(ob, &PyId__check_retval_, &checker) < 0) {
return -1;
}
oldchecker = self->checker;
self->checker = checker;
Py_INCREF(ob); Py_INCREF(ob);
Py_XSETREF(self->restype, ob); Py_XSETREF(self->restype, ob);
Py_XSETREF(self->checker, PyObject_GetAttrString(ob, "_check_retval_")); Py_XDECREF(oldchecker);
if (self->checker == NULL)
PyErr_Clear();
return 0; return 0;
} }
...@@ -3526,9 +3585,12 @@ PyCFuncPtr_new(PyTypeObject *type, PyObject *args, PyObject *kwds) ...@@ -3526,9 +3585,12 @@ PyCFuncPtr_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
like that. like that.
*/ */
/* /*
if (kwds && PyDict_GetItemString(kwds, "options")) { if (kwds && _PyDict_GetItemIdWithError(kwds, &PyId_options)) {
... ...
} }
else if (PyErr_Occurred()) {
return NULL;
}
*/ */
dict = PyType_stgdict((PyObject *)type); dict = PyType_stgdict((PyObject *)type);
...@@ -3605,11 +3667,17 @@ _get_arg(int *pindex, PyObject *name, PyObject *defval, PyObject *inargs, PyObje ...@@ -3605,11 +3667,17 @@ _get_arg(int *pindex, PyObject *name, PyObject *defval, PyObject *inargs, PyObje
Py_INCREF(v); Py_INCREF(v);
return v; return v;
} }
if (kwds && name && (v = PyDict_GetItem(kwds, name))) { if (kwds && name) {
v = PyDict_GetItemWithError(kwds, name);
if (v) {
++*pindex; ++*pindex;
Py_INCREF(v); Py_INCREF(v);
return v; return v;
} }
else if (PyErr_Occurred()) {
return NULL;
}
}
if (defval) { if (defval) {
Py_INCREF(defval); Py_INCREF(defval);
return defval; return defval;
...@@ -3685,7 +3753,7 @@ _build_callargs(PyCFuncPtrObject *self, PyObject *argtypes, ...@@ -3685,7 +3753,7 @@ _build_callargs(PyCFuncPtrObject *self, PyObject *argtypes,
for (i = 0; i < len; ++i) { for (i = 0; i < len; ++i) {
PyObject *item = PyTuple_GET_ITEM(paramflags, i); PyObject *item = PyTuple_GET_ITEM(paramflags, i);
PyObject *ob; PyObject *ob;
int flag; unsigned int flag;
PyObject *name = NULL; PyObject *name = NULL;
PyObject *defval = NULL; PyObject *defval = NULL;
...@@ -3693,7 +3761,7 @@ _build_callargs(PyCFuncPtrObject *self, PyObject *argtypes, ...@@ -3693,7 +3761,7 @@ _build_callargs(PyCFuncPtrObject *self, PyObject *argtypes,
calls below. */ calls below. */
/* We HAVE already checked that the tuple can be parsed with "i|ZO", so... */ /* We HAVE already checked that the tuple can be parsed with "i|ZO", so... */
Py_ssize_t tsize = PyTuple_GET_SIZE(item); Py_ssize_t tsize = PyTuple_GET_SIZE(item);
flag = PyLong_AS_LONG(PyTuple_GET_ITEM(item, 0)); flag = PyLong_AsUnsignedLongMask(PyTuple_GET_ITEM(item, 0));
name = tsize > 1 ? PyTuple_GET_ITEM(item, 1) : NULL; name = tsize > 1 ? PyTuple_GET_ITEM(item, 1) : NULL;
defval = tsize > 2 ? PyTuple_GET_ITEM(item, 2) : NULL; defval = tsize > 2 ? PyTuple_GET_ITEM(item, 2) : NULL;
...@@ -3773,7 +3841,7 @@ _build_callargs(PyCFuncPtrObject *self, PyObject *argtypes, ...@@ -3773,7 +3841,7 @@ _build_callargs(PyCFuncPtrObject *self, PyObject *argtypes,
break; break;
default: default:
PyErr_Format(PyExc_ValueError, PyErr_Format(PyExc_ValueError,
"paramflag %d not yet implemented", flag); "paramflag %u not yet implemented", flag);
goto error; goto error;
break; break;
} }
...@@ -4136,6 +4204,7 @@ _init_pos_args(PyObject *self, PyTypeObject *type, ...@@ -4136,6 +4204,7 @@ _init_pos_args(PyObject *self, PyTypeObject *type,
StgDictObject *dict; StgDictObject *dict;
PyObject *fields; PyObject *fields;
Py_ssize_t i; Py_ssize_t i;
_Py_IDENTIFIER(_fields_);
if (PyType_stgdict((PyObject *)type->tp_base)) { if (PyType_stgdict((PyObject *)type->tp_base)) {
index = _init_pos_args(self, type->tp_base, index = _init_pos_args(self, type->tp_base,
...@@ -4146,9 +4215,13 @@ _init_pos_args(PyObject *self, PyTypeObject *type, ...@@ -4146,9 +4215,13 @@ _init_pos_args(PyObject *self, PyTypeObject *type,
} }
dict = PyType_stgdict((PyObject *)type); dict = PyType_stgdict((PyObject *)type);
fields = PyDict_GetItemString((PyObject *)dict, "_fields_"); fields = _PyDict_GetItemIdWithError((PyObject *)dict, &PyId__fields_);
if (fields == NULL) if (fields == NULL) {
if (PyErr_Occurred()) {
return -1;
}
return index; return index;
}
for (i = 0; for (i = 0;
i < dict->length && (i+index) < PyTuple_GET_SIZE(args); i < dict->length && (i+index) < PyTuple_GET_SIZE(args);
...@@ -4164,7 +4237,8 @@ _init_pos_args(PyObject *self, PyTypeObject *type, ...@@ -4164,7 +4237,8 @@ _init_pos_args(PyObject *self, PyTypeObject *type,
return -1; return -1;
} }
val = PyTuple_GET_ITEM(args, i + index); val = PyTuple_GET_ITEM(args, i + index);
if (kwds && PyDict_GetItem(kwds, name)) { if (kwds) {
if (PyDict_GetItemWithError(kwds, name)) {
PyErr_Format(PyExc_TypeError, PyErr_Format(PyExc_TypeError,
"duplicate values for field %R", "duplicate values for field %R",
name); name);
...@@ -4172,6 +4246,12 @@ _init_pos_args(PyObject *self, PyTypeObject *type, ...@@ -4172,6 +4246,12 @@ _init_pos_args(PyObject *self, PyTypeObject *type,
Py_DECREF(name); Py_DECREF(name);
return -1; return -1;
} }
else if (PyErr_Occurred()) {
Py_DECREF(pair);
Py_DECREF(name);
return -1;
}
}
res = PyObject_SetAttr(self, name, val); res = PyObject_SetAttr(self, name, val);
Py_DECREF(pair); Py_DECREF(pair);
...@@ -4641,6 +4721,10 @@ PyCArrayType_from_ctype(PyObject *itemtype, Py_ssize_t length) ...@@ -4641,6 +4721,10 @@ PyCArrayType_from_ctype(PyObject *itemtype, Py_ssize_t length)
Py_DECREF(key); Py_DECREF(key);
return result; return result;
} }
else if (PyErr_Occurred()) {
Py_DECREF(key);
return NULL;
}
if (!PyType_Check(itemtype)) { if (!PyType_Check(itemtype)) {
PyErr_SetString(PyExc_TypeError, PyErr_SetString(PyExc_TypeError,
......
...@@ -107,9 +107,14 @@ static void ...@@ -107,9 +107,14 @@ static void
TryAddRef(StgDictObject *dict, CDataObject *obj) TryAddRef(StgDictObject *dict, CDataObject *obj)
{ {
IUnknown *punk; IUnknown *punk;
_Py_IDENTIFIER(_needs_com_addref_);
if (NULL == PyDict_GetItemString((PyObject *)dict, "_needs_com_addref_")) if (!_PyDict_GetItemIdWithError((PyObject *)dict, &PyId__needs_com_addref_)) {
if (PyErr_Occurred()) {
PrintError("getting _needs_com_addref_");
}
return; return;
}
punk = *(IUnknown **)obj->b_ptr; punk = *(IUnknown **)obj->b_ptr;
if (punk) if (punk)
......
...@@ -146,7 +146,7 @@ _ctypes_get_errobj(int **pspace) ...@@ -146,7 +146,7 @@ _ctypes_get_errobj(int **pspace)
if (error_object_name == NULL) if (error_object_name == NULL)
return NULL; return NULL;
} }
errobj = PyDict_GetItem(dict, error_object_name); errobj = PyDict_GetItemWithError(dict, error_object_name);
if (errobj) { if (errobj) {
if (!PyCapsule_IsValid(errobj, CTYPES_CAPSULE_NAME_PYMEM)) { if (!PyCapsule_IsValid(errobj, CTYPES_CAPSULE_NAME_PYMEM)) {
PyErr_SetString(PyExc_RuntimeError, PyErr_SetString(PyExc_RuntimeError,
...@@ -155,7 +155,7 @@ _ctypes_get_errobj(int **pspace) ...@@ -155,7 +155,7 @@ _ctypes_get_errobj(int **pspace)
} }
Py_INCREF(errobj); Py_INCREF(errobj);
} }
else { else if (!PyErr_Occurred()) {
void *space = PyMem_Malloc(sizeof(int) * 2); void *space = PyMem_Malloc(sizeof(int) * 2);
if (space == NULL) if (space == NULL)
return NULL; return NULL;
...@@ -171,6 +171,9 @@ _ctypes_get_errobj(int **pspace) ...@@ -171,6 +171,9 @@ _ctypes_get_errobj(int **pspace)
return NULL; return NULL;
} }
} }
else {
return NULL;
}
*pspace = (int *)PyCapsule_GetPointer(errobj, CTYPES_CAPSULE_NAME_PYMEM); *pspace = (int *)PyCapsule_GetPointer(errobj, CTYPES_CAPSULE_NAME_PYMEM);
return errobj; return errobj;
} }
...@@ -685,8 +688,11 @@ static int ConvParam(PyObject *obj, Py_ssize_t index, struct argument *pa) ...@@ -685,8 +688,11 @@ static int ConvParam(PyObject *obj, Py_ssize_t index, struct argument *pa)
#endif #endif
{ {
_Py_IDENTIFIER(_as_parameter_);
PyObject *arg; PyObject *arg;
arg = PyObject_GetAttrString(obj, "_as_parameter_"); if (_PyObject_LookupAttrId(obj, &PyId__as_parameter_, &arg) < 0) {
return -1;
}
/* Which types should we exactly allow here? /* Which types should we exactly allow here?
integers are required for using Python classes integers are required for using Python classes
as parameters (they have to expose the '_as_parameter_' as parameters (they have to expose the '_as_parameter_'
...@@ -1685,11 +1691,14 @@ POINTER(PyObject *self, PyObject *cls) ...@@ -1685,11 +1691,14 @@ POINTER(PyObject *self, PyObject *cls)
PyObject *key; PyObject *key;
char *buf; char *buf;
result = PyDict_GetItem(_ctypes_ptrtype_cache, cls); result = PyDict_GetItemWithError(_ctypes_ptrtype_cache, cls);
if (result) { if (result) {
Py_INCREF(result); Py_INCREF(result);
return result; return result;
} }
else if (PyErr_Occurred()) {
return NULL;
}
if (PyUnicode_CheckExact(cls)) { if (PyUnicode_CheckExact(cls)) {
const char *name = PyUnicode_AsUTF8(cls); const char *name = PyUnicode_AsUTF8(cls);
if (name == NULL) if (name == NULL)
...@@ -1745,9 +1754,13 @@ pointer(PyObject *self, PyObject *arg) ...@@ -1745,9 +1754,13 @@ pointer(PyObject *self, PyObject *arg)
PyObject *result; PyObject *result;
PyObject *typ; PyObject *typ;
typ = PyDict_GetItem(_ctypes_ptrtype_cache, (PyObject *)Py_TYPE(arg)); typ = PyDict_GetItemWithError(_ctypes_ptrtype_cache, (PyObject *)Py_TYPE(arg));
if (typ) if (typ) {
return PyObject_CallFunctionObjArgs(typ, arg, NULL); return PyObject_CallFunctionObjArgs(typ, arg, NULL);
}
else if (PyErr_Occurred()) {
return NULL;
}
typ = POINTER(NULL, (PyObject *)Py_TYPE(arg)); typ = POINTER(NULL, (PyObject *)Py_TYPE(arg));
if (typ == NULL) if (typ == NULL)
return NULL; return NULL;
......
...@@ -1147,7 +1147,7 @@ c_set(void *ptr, PyObject *value, Py_ssize_t size) ...@@ -1147,7 +1147,7 @@ c_set(void *ptr, PyObject *value, Py_ssize_t size)
} }
if (PyLong_Check(value)) if (PyLong_Check(value))
{ {
long longval = PyLong_AS_LONG(value); long longval = PyLong_AsLong(value);
if (longval < 0 || longval >= 256) if (longval < 0 || longval >= 256)
goto error; goto error;
*(char *)ptr = (char)longval; *(char *)ptr = (char)longval;
......
...@@ -281,13 +281,15 @@ MakeFields(PyObject *type, CFieldObject *descr, ...@@ -281,13 +281,15 @@ MakeFields(PyObject *type, CFieldObject *descr,
static int static int
MakeAnonFields(PyObject *type) MakeAnonFields(PyObject *type)
{ {
_Py_IDENTIFIER(_anonymous_);
PyObject *anon; PyObject *anon;
PyObject *anon_names; PyObject *anon_names;
Py_ssize_t i; Py_ssize_t i;
anon = PyObject_GetAttrString(type, "_anonymous_"); if (_PyObject_LookupAttrId(type, &PyId__anonymous_, &anon) < 0) {
return -1;
}
if (anon == NULL) { if (anon == NULL) {
PyErr_Clear();
return 0; return 0;
} }
anon_names = PySequence_Fast(anon, "_anonymous_ must be a sequence"); anon_names = PySequence_Fast(anon, "_anonymous_ must be a sequence");
...@@ -335,13 +337,17 @@ MakeAnonFields(PyObject *type) ...@@ -335,13 +337,17 @@ MakeAnonFields(PyObject *type)
int int
PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct) 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; StgDictObject *stgdict, *basedict;
Py_ssize_t len, offset, size, align, i; Py_ssize_t len, offset, size, align, i;
Py_ssize_t union_size, total_align; Py_ssize_t union_size, total_align;
Py_ssize_t field_size = 0; Py_ssize_t field_size = 0;
int bitofs; int bitofs;
PyObject *isPacked; PyObject *tmp;
int pack = 0; int isPacked;
int pack;
Py_ssize_t ffi_ofs; Py_ssize_t ffi_ofs;
int big_endian; int big_endian;
...@@ -356,32 +362,59 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct ...@@ -356,32 +362,59 @@ PyCStructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct
if (fields == NULL) if (fields == NULL)
return 0; return 0;
#ifdef WORDS_BIGENDIAN if (_PyObject_LookupAttrId(type, &PyId__swappedbytes_, &tmp) < 0) {
big_endian = PyObject_HasAttrString(type, "_swappedbytes_") ? 0 : 1; return -1;
#else }
big_endian = PyObject_HasAttrString(type, "_swappedbytes_") ? 1 : 0; if (tmp) {
#endif Py_DECREF(tmp);
big_endian = !PY_BIG_ENDIAN;
}
else {
big_endian = PY_BIG_ENDIAN;
}
use_broken_old_ctypes_semantics = \ if (_PyObject_LookupAttrId(type,
PyObject_HasAttrString(type, "_use_broken_old_ctypes_structure_semantics_"); &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 (_PyObject_LookupAttrId(type, &PyId__pack_, &tmp) < 0) {
if (isPacked) { return -1;
pack = _PyLong_AsInt(isPacked); }
if (pack < 0 || PyErr_Occurred()) { if (tmp) {
Py_XDECREF(isPacked); 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, PyErr_SetString(PyExc_ValueError,
"_pack_ must be a non-negative integer"); "_pack_ must be a non-negative integer");
}
return -1; return -1;
} }
Py_DECREF(isPacked); }
} else else {
PyErr_Clear(); isPacked = 0;
pack = 0;
}
len = PySequence_Length(fields); len = PySequence_Size(fields);
if (len == -1) { if (len == -1) {
if (PyErr_ExceptionMatches(PyExc_TypeError)) {
PyErr_SetString(PyExc_TypeError, PyErr_SetString(PyExc_TypeError,
"'_fields_' must be a sequence of pairs"); "'_fields_' must be a sequence of pairs");
}
return -1; return -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