diff options
author | Miss Skeleton (bot) <31488909+miss-islington@users.noreply.github.com> | 2020-10-14 09:09:44 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-14 09:09:44 (GMT) |
commit | 391a544f2a52673f6630c672e89840fd6ac36723 (patch) | |
tree | 06759ba79e72debd3425d2f0d4111f1bdd60d204 /Python | |
parent | 881a13cad534cf3fe4474579c22235a15d3ba27b (diff) | |
download | cpython-391a544f2a52673f6630c672e89840fd6ac36723.zip cpython-391a544f2a52673f6630c672e89840fd6ac36723.tar.gz cpython-391a544f2a52673f6630c672e89840fd6ac36723.tar.bz2 |
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 8287aadb75f6bd0154996424819334cd3839707c)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
Diffstat (limited to 'Python')
-rw-r--r-- | Python/import.c | 23 |
1 files changed, 13 insertions, 10 deletions
diff --git a/Python/import.c b/Python/import.c index 0e2e7c3..5e39a2f 100644 --- a/Python/import.c +++ b/Python/import.c @@ -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 remove_module(PyThreadState *tstate, PyObject *name) { @@ -913,18 +917,17 @@ remove_module(PyThreadState *tstate, PyObject *name) _PyErr_Fetch(tstate, &type, &value, &traceback); PyObject *modules = tstate->interp->modules; - if (!PyMapping_HasKey(modules, name)) { - goto out; + if (PyDict_CheckExact(modules)) { + PyObject *mod = _PyDict_Pop(modules, name, Py_None); + Py_XDECREF(mod); } - if (PyMapping_DelItem(modules, name) < 0) { - _PyErr_SetString(tstate, PyExc_RuntimeError, - "deleting key in sys.modules failed"); - _PyErr_ChainExceptions(type, value, traceback); - return; + else if (PyMapping_DelItem(modules, name) < 0) { + if (_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) { + _PyErr_Clear(tstate); + } } -out: - _PyErr_Restore(tstate, type, value, traceback); + _PyErr_ChainExceptions(type, value, traceback); } |