-
-
Notifications
You must be signed in to change notification settings - Fork 33.2k
Description
pywin32 has, since the 90s, used c++ to "inherit" from a PyObject in some cases. In short, it ends up something like:
class MyObject : public PyObject {
virtual void some_helper();
}
With a layout like this, a reinterpret_cast between a MyObject * and a PyObject * will create invalid pointers.
Consider something like the following:
void MyObject::some_helper() {
Py_DECREF(this);
}
This ends up being a macro which uses _PyObject_CAST on the param passed to Py_DECREF. In 3.10, this uses a traditional "c" cast , but in 3.11 it turned into a reinterpret_cast. In the above example, this causes Py_DECREF to be called with an invalid PyObject * - which typically doesn't crash at the time, but instead corrupts memory causing a difficult to diagnose crash some time later.
Changing the code to use explicit static_cast<>, or the old-school (PyObject *) cast makes things work, but it would be error prone as it would be easy to miss places where it's used via non-obvious nested macros. It also shouldn't be necessary to make this kind of change - c++ code which has worked for this long should continue to work.