bpo-39382: Avoid dangling object use in abstract_issubclass() (GH-18530)

Hold reference of __bases__ tuple until tuple item is done with, because by
dropping the reference the item may be destroyed.
This commit is contained in:
Yonatan Goldschmidt 2020-02-22 15:11:48 +02:00 committed by GitHub
parent a025d4ca99
commit 1c56f8ffad
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 34 additions and 3 deletions

View file

@ -2379,9 +2379,16 @@ abstract_issubclass(PyObject *derived, PyObject *cls)
int r = 0;
while (1) {
if (derived == cls)
if (derived == cls) {
Py_XDECREF(bases); /* See below comment */
return 1;
bases = abstract_get_bases(derived);
}
/* Use XSETREF to drop bases reference *after* finishing with
derived; bases might be the only reference to it.
XSETREF is used instead of SETREF, because bases is NULL on the
first iteration of the loop.
*/
Py_XSETREF(bases, abstract_get_bases(derived));
if (bases == NULL) {
if (PyErr_Occurred())
return -1;
@ -2395,7 +2402,6 @@ abstract_issubclass(PyObject *derived, PyObject *cls)
/* Avoid recursivity in the single inheritance case */
if (n == 1) {
derived = PyTuple_GET_ITEM(bases, 0);
Py_DECREF(bases);
continue;
}
for (i = 0; i < n; i++) {