| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 6111d5d commit acda9f3
2 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,5 @@ | |||
| 1 | + Fix a race condition on setting a type ``__bases__`` attribute: the internal | ||
| 2 | + function ``add_subclass()`` now gets the ``PyTypeObject.tp_subclasses`` | ||
| 3 | + member after calling :c:func:`PyWeakref_NewRef` which can trigger a garbage | ||
| 4 | + collection which can indirectly modify ``PyTypeObject.tp_subclasses``. Patch | ||
| 5 | + by Victor Stinner. | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -6384,24 +6384,29 @@ PyType_Ready(PyTypeObject *type) | |||
| 6384 | 6384 | static int | |
| 6385 | 6385 | add_subclass(PyTypeObject *base, PyTypeObject *type) | |
| 6386 | 6386 | { | |
| 6387 | - int result = -1; | ||
| 6388 | - PyObject *dict, *key, *newobj; | ||
| 6387 | + PyObject *key = PyLong_FromVoidPtr((void *) type); | ||
| 6388 | + if (key == NULL) | ||
| 6389 | + return -1; | ||
| 6389 | 6390 | ||
| 6390 | - dict = base->tp_subclasses; | ||
| 6391 | + PyObject *ref = PyWeakref_NewRef((PyObject *)type, NULL); | ||
| 6392 | + if (ref == NULL) { | ||
| 6393 | + Py_DECREF(key); | ||
| 6394 | + return -1; | ||
| 6395 | + } | ||
| 6396 | + | ||
| 6397 | + // Only get tp_subclasses after creating the key and value. | ||
| 6398 | + // PyWeakref_NewRef() can trigger a garbage collection which can execute | ||
| 6399 | + // arbitrary Python code and so modify base->tp_subclasses. | ||
| 6400 | + PyObject *dict = base->tp_subclasses; | ||
| 6391 | 6401 | if (dict == NULL) { | |
| 6392 | 6402 | base->tp_subclasses = dict = PyDict_New(); | |
| 6393 | 6403 | if (dict == NULL) | |
| 6394 | 6404 | return -1; | |
| 6395 | 6405 | } | |
| 6396 | 6406 | assert(PyDict_CheckExact(dict)); | |
| 6397 | - key = PyLong_FromVoidPtr((void *) type); | ||
| 6398 | - if (key == NULL) | ||
| 6399 | - return -1; | ||
| 6400 | - newobj = PyWeakref_NewRef((PyObject *)type, NULL); | ||
| 6401 | - if (newobj != NULL) { | ||
| 6402 | - result = PyDict_SetItem(dict, key, newobj); | ||
| 6403 | - Py_DECREF(newobj); | ||
| 6404 | - } | ||
| 6407 | + | ||
| 6408 | + int result = PyDict_SetItem(dict, key, ref); | ||
| 6409 | + Py_DECREF(ref); | ||
| 6405 | 6410 | Py_DECREF(key); | |
| 6406 | 6411 | return result; | |
| 6407 | 6412 | } | |
| Back | FazBrowse Home | New Git URL |
0 commit comments