PyObject_IsInstance is not safe when used to check if the object is an instance of specified builtin type. Typical code: rc = PyObject_IsInstance(obj, &Someting_Type); if (rc < 0) return NULL; if (rc) { SometingObject *something = (SometingObject *)obj; something->some_field ... } The __class__ attribute can be modified and PyObject_IsInstance() can return true if the object has not layout compatible with specified structure. And even worse, __class__ can be dynamic property and PyObject_IsInstance() can execute arbitrary Python code, that can invalidate cached values of pointers and sizes in C code. More safe way would be to use PyObject_IsSubclass(). rc = PyObject_IsSubclass((Py_Object *)obj->ob_type, &Someting_Type); if (rc < 0) return NULL; if (rc) { SometingObject *something = (SometingObject *)obj; something->some_field ... } For example see issue24102 [1], issue24091 [2] and many other issues opened by pkt. [1] http://bugs.python.org/issue24102 [2] http://bugs.python.org/issue24091
Serhiy Storchaka wrote:
PyObject_IsInstance is not safe when used to check if the object is an instance of specified builtin type.
The __class__ attribute can be modified and PyObject_IsInstance() can return true if the object has not layout compatible with specified structure.
Code that requires a particular C layout should be using PyObject_TypeCheck, not PyObject_IsInstance. -- Greg
On 18.05.15 15:14, Greg Ewing wrote:
Serhiy Storchaka wrote:
PyObject_IsInstance is not safe when used to check if the object is an instance of specified builtin type.
The __class__ attribute can be modified and PyObject_IsInstance() can return true if the object has not layout compatible with specified structure.
Code that requires a particular C layout should be using PyObject_TypeCheck, not PyObject_IsInstance.
Thank you. I didn't know about this helper. Looks as most (if not all) usages of PyObject_IsInstance are not correct. May be modify PyObject_IsInstance so that it will never return true if layouts are not compatible?
Serhiy Storchaka wrote:
May be modify PyObject_IsInstance so that it will never return true if layouts are not compatible?
That wouldn't be a good idea, since PyObject_IsInstance is meant to reflect the behaviour of python's isinstance() function, which doesn't care about C layouts. -- Greg
participants (2)
-
Greg Ewing
-
Serhiy Storchaka