mirror of
https://github.com/python/cpython.git
synced 2025-07-28 05:34:31 +00:00
Bug #742342: make Python stop segfaulting on infinitely-recursive reload()s. Fixed by patch #922167.
Will backport.
This commit is contained in:
parent
f567ca3e1a
commit
276887b16d
7 changed files with 62 additions and 2 deletions
|
@ -340,6 +340,25 @@ imp_release_lock(PyObject *self, PyObject *noargs)
|
|||
return Py_None;
|
||||
}
|
||||
|
||||
PyObject *
|
||||
PyImport_GetModulesReloading(void)
|
||||
{
|
||||
PyInterpreterState *interp = PyThreadState_Get()->interp;
|
||||
if (interp->modules_reloading == NULL)
|
||||
Py_FatalError("PyImport_GetModuleDict: no modules_reloading dictionary!");
|
||||
return interp->modules_reloading;
|
||||
}
|
||||
|
||||
static void
|
||||
imp_modules_reloading_clear (void)
|
||||
{
|
||||
PyInterpreterState *interp = PyThreadState_Get()->interp;
|
||||
if (interp->modules_reloading == NULL)
|
||||
return;
|
||||
PyDict_Clear(interp->modules_reloading);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Helper for sys */
|
||||
|
||||
PyObject *
|
||||
|
@ -499,6 +518,7 @@ PyImport_Cleanup(void)
|
|||
PyDict_Clear(modules);
|
||||
interp->modules = NULL;
|
||||
Py_DECREF(modules);
|
||||
Py_CLEAR(interp->modules_reloading);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2401,8 +2421,9 @@ import_submodule(PyObject *mod, char *subname, char *fullname)
|
|||
PyObject *
|
||||
PyImport_ReloadModule(PyObject *m)
|
||||
{
|
||||
PyObject *modules_reloading = PyImport_GetModulesReloading();
|
||||
PyObject *modules = PyImport_GetModuleDict();
|
||||
PyObject *path = NULL, *loader = NULL;
|
||||
PyObject *path = NULL, *loader = NULL, *existing_m = NULL;
|
||||
char *name, *subname;
|
||||
char buf[MAXPATHLEN+1];
|
||||
struct filedescr *fdp;
|
||||
|
@ -2423,20 +2444,30 @@ PyImport_ReloadModule(PyObject *m)
|
|||
name);
|
||||
return NULL;
|
||||
}
|
||||
if ((existing_m = PyDict_GetItemString(modules_reloading, name)) != NULL) {
|
||||
/* Due to a recursive reload, this module is already being reloaded. */
|
||||
Py_INCREF(existing_m);
|
||||
return existing_m;
|
||||
}
|
||||
PyDict_SetItemString(modules_reloading, name, m);
|
||||
|
||||
subname = strrchr(name, '.');
|
||||
if (subname == NULL)
|
||||
subname = name;
|
||||
else {
|
||||
PyObject *parentname, *parent;
|
||||
parentname = PyString_FromStringAndSize(name, (subname-name));
|
||||
if (parentname == NULL)
|
||||
if (parentname == NULL) {
|
||||
imp_modules_reloading_clear();
|
||||
return NULL;
|
||||
}
|
||||
parent = PyDict_GetItem(modules, parentname);
|
||||
if (parent == NULL) {
|
||||
PyErr_Format(PyExc_ImportError,
|
||||
"reload(): parent %.200s not in sys.modules",
|
||||
PyString_AS_STRING(parentname));
|
||||
Py_DECREF(parentname);
|
||||
imp_modules_reloading_clear();
|
||||
return NULL;
|
||||
}
|
||||
Py_DECREF(parentname);
|
||||
|
@ -2451,6 +2482,7 @@ PyImport_ReloadModule(PyObject *m)
|
|||
|
||||
if (fdp == NULL) {
|
||||
Py_XDECREF(loader);
|
||||
imp_modules_reloading_clear();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -2467,6 +2499,7 @@ PyImport_ReloadModule(PyObject *m)
|
|||
*/
|
||||
PyDict_SetItemString(modules, name, m);
|
||||
}
|
||||
imp_modules_reloading_clear ();
|
||||
return newm;
|
||||
}
|
||||
|
||||
|
|
|
@ -68,6 +68,7 @@ PyInterpreterState_New(void)
|
|||
Py_FatalError("Can't initialize threads for interpreter");
|
||||
#endif
|
||||
interp->modules = NULL;
|
||||
interp->modules_reloading = NULL;
|
||||
interp->sysdict = NULL;
|
||||
interp->builtins = NULL;
|
||||
interp->tstate_head = NULL;
|
||||
|
@ -107,6 +108,7 @@ PyInterpreterState_Clear(PyInterpreterState *interp)
|
|||
Py_CLEAR(interp->codec_search_cache);
|
||||
Py_CLEAR(interp->codec_error_registry);
|
||||
Py_CLEAR(interp->modules);
|
||||
Py_CLEAR(interp->modules_reloading);
|
||||
Py_CLEAR(interp->sysdict);
|
||||
Py_CLEAR(interp->builtins);
|
||||
}
|
||||
|
|
|
@ -194,6 +194,9 @@ Py_InitializeEx(int install_sigs)
|
|||
interp->modules = PyDict_New();
|
||||
if (interp->modules == NULL)
|
||||
Py_FatalError("Py_Initialize: can't make modules dictionary");
|
||||
interp->modules_reloading = PyDict_New();
|
||||
if (interp->modules_reloading == NULL)
|
||||
Py_FatalError("Py_Initialize: can't make modules_reloading dictionary");
|
||||
|
||||
#ifdef Py_USING_UNICODE
|
||||
/* Init Unicode implementation; relies on the codec registry */
|
||||
|
@ -531,6 +534,7 @@ Py_NewInterpreter(void)
|
|||
/* XXX The following is lax in error checking */
|
||||
|
||||
interp->modules = PyDict_New();
|
||||
interp->modules_reloading = PyDict_New();
|
||||
|
||||
bimod = _PyImport_FindExtension("__builtin__", "__builtin__");
|
||||
if (bimod != NULL) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue