[Python-checkins] bpo-41993: Fix possible issues in remove_module() (GH-22631) (GH-22647)
Miss Skeleton (bot)
webhook-mailer at python.org
Wed Oct 14 05:10:19 EDT 2020
https://github.com/python/cpython/commit/391a544f2a52673f6630c672e89840fd6ac36723
commit: 391a544f2a52673f6630c672e89840fd6ac36723
branch: 3.9
author: Miss Skeleton (bot) <31488909+miss-islington at users.noreply.github.com>
committer: GitHub <noreply at github.com>
date: 2020-10-14T12:09:44+03:00
summary:
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 at gmail.com>
files:
A Misc/NEWS.d/next/Core and Builtins/2020-10-10-13-53-52.bpo-41993.YMzixQ.rst
M Python/import.c
diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-10-10-13-53-52.bpo-41993.YMzixQ.rst b/Misc/NEWS.d/next/Core and Builtins/2020-10-10-13-53-52.bpo-41993.YMzixQ.rst
new file mode 100644
index 0000000000000..3669cf11ea4cd
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2020-10-10-13-53-52.bpo-41993.YMzixQ.rst
@@ -0,0 +1,2 @@
+Fixed potential issues with removing not completely initialized module from
+``sys.modules`` when import fails.
diff --git a/Python/import.c b/Python/import.c
index 0e2e7c370868f..5e39a2fb9a02e 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);
}
More information about the Python-checkins
mailing list