summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2020-03-17 17:09:46 (GMT)
committerGitHub <noreply@github.com>2020-03-17 17:09:46 (GMT)
commit5b1ef200d31a74a9b478d0217d73ed0a659a8a06 (patch)
tree3a3afde33a456ac49284058c00b1d685c54bcf3c /Objects
parent52268941f37e3e27bd01792b081877ec3bc9ce12 (diff)
downloadcpython-5b1ef200d31a74a9b478d0217d73ed0a659a8a06.zip
cpython-5b1ef200d31a74a9b478d0217d73ed0a659a8a06.tar.gz
cpython-5b1ef200d31a74a9b478d0217d73ed0a659a8a06.tar.bz2
bpo-39824: module_traverse() don't call m_traverse if md_state=NULL (GH-18738)
Extension modules: m_traverse, m_clear and m_free functions of PyModuleDef are no longer called if the module state was requested but is not allocated yet. This is the case immediately after the module is created and before the module is executed (Py_mod_exec function). More precisely, these functions are not called if m_size is greater than 0 and the module state (as returned by PyModule_GetState()) is NULL. Extension modules without module state (m_size <= 0) are not affected. Co-Authored-By: Petr Viktorin <encukou@gmail.com>
Diffstat (limited to 'Objects')
-rw-r--r--Objects/moduleobject.c36
1 files changed, 13 insertions, 23 deletions
diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c
index c581951..f02ca75 100644
--- a/Objects/moduleobject.c
+++ b/Objects/moduleobject.c
@@ -26,16 +26,6 @@ static PyMemberDef module_members[] = {
};
-/* Helper for sanity check for traverse not handling m_state == NULL
- * Issue #32374 */
-#ifdef Py_DEBUG
-static int
-bad_traverse_test(PyObject *self, void *arg) {
- assert(self != NULL);
- return 0;
-}
-#endif
-
PyTypeObject PyModuleDef_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"moduledef", /* tp_name */
@@ -360,16 +350,6 @@ PyModule_FromDefAndSpec2(struct PyModuleDef* def, PyObject *spec, int module_api
}
}
- /* Sanity check for traverse not handling m_state == NULL
- * This doesn't catch all possible cases, but in many cases it should
- * make many cases of invalid code crash or raise Valgrind issues
- * sooner than they would otherwise.
- * Issue #32374 */
-#ifdef Py_DEBUG
- if (def->m_traverse != NULL) {
- def->m_traverse(m, bad_traverse_test, NULL);
- }
-#endif
Py_DECREF(nameobj);
return m;
@@ -687,8 +667,12 @@ module_dealloc(PyModuleObject *m)
}
if (m->md_weaklist != NULL)
PyObject_ClearWeakRefs((PyObject *) m);
- if (m->md_def && m->md_def->m_free)
+ /* bpo-39824: Don't call m_free() if m_size > 0 and md_state=NULL */
+ if (m->md_def && m->md_def->m_free
+ && (m->md_def->m_size <= 0 || m->md_state != NULL))
+ {
m->md_def->m_free(m);
+ }
Py_XDECREF(m->md_dict);
Py_XDECREF(m->md_name);
if (m->md_state != NULL)
@@ -770,7 +754,10 @@ module_getattro(PyModuleObject *m, PyObject *name)
static int
module_traverse(PyModuleObject *m, visitproc visit, void *arg)
{
- if (m->md_def && m->md_def->m_traverse) {
+ /* bpo-39824: Don't call m_traverse() if m_size > 0 and md_state=NULL */
+ if (m->md_def && m->md_def->m_traverse
+ && (m->md_def->m_size <= 0 || m->md_state != NULL))
+ {
int res = m->md_def->m_traverse((PyObject*)m, visit, arg);
if (res)
return res;
@@ -782,7 +769,10 @@ module_traverse(PyModuleObject *m, visitproc visit, void *arg)
static int
module_clear(PyModuleObject *m)
{
- if (m->md_def && m->md_def->m_clear) {
+ /* bpo-39824: Don't call m_clear() if m_size > 0 and md_state=NULL */
+ if (m->md_def && m->md_def->m_clear
+ && (m->md_def->m_size <= 0 || m->md_state != NULL))
+ {
int res = m->md_def->m_clear((PyObject*)m);
if (PyErr_Occurred()) {
PySys_FormatStderr("Exception ignored in m_clear of module%s%V\n",