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>
This commit is contained in:
Victor Stinner 2020-03-17 18:09:46 +01:00 committed by GitHub
parent 52268941f3
commit 5b1ef200d3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 91 additions and 144 deletions

View file

@ -267,29 +267,6 @@ class MultiPhaseExtensionModuleTests(abc.LoaderTests):
self.assertEqual(module.__name__, name)
self.assertEqual(module.__doc__, "Module named in %s" % lang)
@unittest.skipIf(not hasattr(sys, 'gettotalrefcount'),
'--with-pydebug has to be enabled for this test')
def test_bad_traverse(self):
''' Issue #32374: Test that traverse fails when accessing per-module
state before Py_mod_exec was executed.
(Multiphase initialization modules only)
'''
script = """if True:
try:
from test import support
import importlib.util as util
spec = util.find_spec('_testmultiphase')
spec.name = '_testmultiphase_with_bad_traverse'
with support.SuppressCrashReport():
m = spec.loader.create_module(spec)
except:
# Prevent Python-level exceptions from
# ending the process with non-zero status
# (We are testing for a crash in C-code)
pass"""
assert_python_failure("-c", script)
(Frozen_MultiPhaseExtensionModuleTests,
Source_MultiPhaseExtensionModuleTests