summaryrefslogtreecommitdiffstats
path: root/Python/Python-ast.c
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2020-07-03 12:15:53 (GMT)
committerGitHub <noreply@github.com>2020-07-03 12:15:53 (GMT)
commit91e1bc18bd467a13bceb62e16fbc435b33381c82 (patch)
treec0b38793683a3a4f0c72b471e14ca0bc622bd33d /Python/Python-ast.c
parent74419f0c64959bb8392fcf3659058410423038e1 (diff)
downloadcpython-91e1bc18bd467a13bceb62e16fbc435b33381c82.zip
cpython-91e1bc18bd467a13bceb62e16fbc435b33381c82.tar.gz
cpython-91e1bc18bd467a13bceb62e16fbc435b33381c82.tar.bz2
bpo-41194: The _ast module cannot be loaded more than once (GH-21290)
Fix a crash in the _ast module: it can no longer be loaded more than once. It now uses a global state rather than a module state. * Move _ast module state: use a global state instead. * Set _astmodule.m_size to -1, so the extension cannot be loaded more than once.
Diffstat (limited to 'Python/Python-ast.c')
-rw-r--r--Python/Python-ast.c70
1 files changed, 32 insertions, 38 deletions
diff --git a/Python/Python-ast.c b/Python/Python-ast.c
index 3296b06..844033e 100644
--- a/Python/Python-ast.c
+++ b/Python/Python-ast.c
@@ -224,13 +224,12 @@ typedef struct {
} astmodulestate;
+static astmodulestate global_ast_state;
+
static astmodulestate *
-get_ast_state(PyObject *module)
+get_ast_state(PyObject *Py_UNUSED(module))
{
- assert(module != NULL);
- void *state = PyModule_GetState(module);
- assert(state != NULL);
- return (astmodulestate *)state;
+ return &global_ast_state;
}
static int astmodule_clear(PyObject *module)
@@ -679,17 +678,14 @@ static void astmodule_free(void* module) {
static struct PyModuleDef _astmodule = {
PyModuleDef_HEAD_INIT,
- "_ast",
- NULL,
- sizeof(astmodulestate),
- NULL,
- NULL,
- astmodule_traverse,
- astmodule_clear,
- astmodule_free,
+ .m_name = "_ast",
+ .m_size = -1,
+ .m_traverse = astmodule_traverse,
+ .m_clear = astmodule_clear,
+ .m_free = astmodule_free,
};
-#define astmodulestate_global get_ast_state(PyState_FindModule(&_astmodule))
+#define get_global_ast_state() (&global_ast_state)
static int init_identifiers(astmodulestate *state)
{
@@ -1135,7 +1131,7 @@ ast_type_init(PyObject *self, PyObject *args, PyObject *kw)
Py_ssize_t i, numfields = 0;
int res = -1;
PyObject *key, *value, *fields;
- astmodulestate *state = astmodulestate_global;
+ astmodulestate *state = get_global_ast_state();
if (_PyObject_LookupAttr((PyObject*)Py_TYPE(self), state->_fields, &fields) < 0) {
goto cleanup;
}
@@ -1204,7 +1200,7 @@ ast_type_init(PyObject *self, PyObject *args, PyObject *kw)
static PyObject *
ast_type_reduce(PyObject *self, PyObject *unused)
{
- astmodulestate *state = astmodulestate_global;
+ astmodulestate *state = get_global_ast_state();
PyObject *dict;
if (_PyObject_LookupAttr(self, state->__dict__, &dict) < 0) {
return NULL;
@@ -1414,18 +1410,7 @@ static int add_ast_fields(astmodulestate *state)
static int init_types(void)
{
- PyObject *module = PyState_FindModule(&_astmodule);
- if (module == NULL) {
- module = PyModule_Create(&_astmodule);
- if (!module) {
- return 0;
- }
- if (PyState_AddModule(module, &_astmodule) < 0) {
- return 0;
- }
- }
-
- astmodulestate *state = get_ast_state(module);
+ astmodulestate *state = get_global_ast_state();
if (state->initialized) return 1;
if (init_identifiers(state) < 0) return 0;
state->AST_type = PyType_FromSpec(&AST_type_spec);
@@ -9857,12 +9842,15 @@ obj2ast_type_ignore(astmodulestate *state, PyObject* obj, type_ignore_ty* out,
PyMODINIT_FUNC
PyInit__ast(void)
{
- PyObject *m;
- if (!init_types()) return NULL;
- m = PyState_FindModule(&_astmodule);
- if (!m) return NULL;
+ PyObject *m = PyModule_Create(&_astmodule);
+ if (!m) {
+ return NULL;
+ }
astmodulestate *state = get_ast_state(m);
+ if (!init_types()) {
+ goto error;
+ }
if (PyModule_AddObject(m, "AST", state->AST_type) < 0) {
goto error;
}
@@ -10303,6 +10291,7 @@ PyInit__ast(void)
}
Py_INCREF(state->TypeIgnore_type);
return m;
+
error:
Py_DECREF(m);
return NULL;
@@ -10311,9 +10300,11 @@ error:
PyObject* PyAST_mod2obj(mod_ty t)
{
- if (!init_types())
+ if (!init_types()) {
return NULL;
- astmodulestate *state = astmodulestate_global;
+ }
+
+ astmodulestate *state = get_global_ast_state();
return ast2obj_mod(state, t);
}
@@ -10327,7 +10318,7 @@ mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode)
return NULL;
}
- astmodulestate *state = astmodulestate_global;
+ astmodulestate *state = get_global_ast_state();
PyObject *req_type[3];
req_type[0] = state->Module_type;
req_type[1] = state->Expression_type;
@@ -10335,8 +10326,9 @@ mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode)
assert(0 <= mode && mode <= 2);
- if (!init_types())
+ if (!init_types()) {
return NULL;
+ }
isinstance = PyObject_IsInstance(ast, req_type[mode]);
if (isinstance == -1)
@@ -10356,9 +10348,11 @@ mod_ty PyAST_obj2mod(PyObject* ast, PyArena* arena, int mode)
int PyAST_Check(PyObject* obj)
{
- if (!init_types())
+ if (!init_types()) {
return -1;
- astmodulestate *state = astmodulestate_global;
+ }
+
+ astmodulestate *state = get_global_ast_state();
return PyObject_IsInstance(obj, state->AST_type);
}