mirror of
https://github.com/python/cpython.git
synced 2025-09-27 02:39:58 +00:00
bpo-41993: Fix possible issues in remove_module() (GH-22631) (GH-22647)
* PyMapping_HasKey() is not safe because it silences all exceptions and can return incorrect result.
* Informative exceptions from PyMapping_DelItem() are overridden with RuntimeError and
the original exception raised before calling remove_module() is lost.
* There is a race condition between PyMapping_HasKey() and PyMapping_DelItem().
(cherry picked from commit 8287aadb75
)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
This commit is contained in:
parent
881a13cad5
commit
391a544f2a
2 changed files with 15 additions and 10 deletions
|
@ -0,0 +1,2 @@
|
||||||
|
Fixed potential issues with removing not completely initialized module from
|
||||||
|
``sys.modules`` when import fails.
|
|
@ -905,7 +905,11 @@ PyImport_AddModule(const char *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Remove name from sys.modules, if it's there. */
|
/* Remove name from sys.modules, if it's there.
|
||||||
|
* Can be called with an exception raised.
|
||||||
|
* If fail to remove name a new exception will be chained with the old
|
||||||
|
* exception, otherwise the old exception is preserved.
|
||||||
|
*/
|
||||||
static void
|
static void
|
||||||
remove_module(PyThreadState *tstate, PyObject *name)
|
remove_module(PyThreadState *tstate, PyObject *name)
|
||||||
{
|
{
|
||||||
|
@ -913,18 +917,17 @@ remove_module(PyThreadState *tstate, PyObject *name)
|
||||||
_PyErr_Fetch(tstate, &type, &value, &traceback);
|
_PyErr_Fetch(tstate, &type, &value, &traceback);
|
||||||
|
|
||||||
PyObject *modules = tstate->interp->modules;
|
PyObject *modules = tstate->interp->modules;
|
||||||
if (!PyMapping_HasKey(modules, name)) {
|
if (PyDict_CheckExact(modules)) {
|
||||||
goto out;
|
PyObject *mod = _PyDict_Pop(modules, name, Py_None);
|
||||||
|
Py_XDECREF(mod);
|
||||||
|
}
|
||||||
|
else if (PyMapping_DelItem(modules, name) < 0) {
|
||||||
|
if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
|
||||||
|
_PyErr_Clear(tstate);
|
||||||
}
|
}
|
||||||
if (PyMapping_DelItem(modules, name) < 0) {
|
|
||||||
_PyErr_SetString(tstate, PyExc_RuntimeError,
|
|
||||||
"deleting key in sys.modules failed");
|
|
||||||
_PyErr_ChainExceptions(type, value, traceback);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
_PyErr_ChainExceptions(type, value, traceback);
|
||||||
_PyErr_Restore(tstate, type, value, traceback);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue