From e1bd0cd37b1816092761e5ad5f2d0464c0e78fbb Mon Sep 17 00:00:00 2001 From: Stan Ulbrych <89152624+StanFromIreland@users.noreply.github.com> Date: Sat, 21 Feb 2026 12:52:40 +0000 Subject: [PATCH] gh-145058: Add input validation to `_PyImport_LazyImportModuleLevelObject` (#145068) --- Lib/test/test_import/test_lazy_imports.py | 9 +++++++++ .../2026-02-21-09-47-45.gh-issue-145058.e-RBw-.rst | 2 ++ Python/import.c | 11 +++++++++++ 3 files changed, 22 insertions(+) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2026-02-21-09-47-45.gh-issue-145058.e-RBw-.rst diff --git a/Lib/test/test_import/test_lazy_imports.py b/Lib/test/test_import/test_lazy_imports.py index a4c9c14ae2b..dc185c070ac 100644 --- a/Lib/test/test_import/test_lazy_imports.py +++ b/Lib/test/test_import/test_lazy_imports.py @@ -393,6 +393,15 @@ def test_dunder_lazy_import_used(self): import test.test_import.data.lazy_imports.dunder_lazy_import_used self.assertIn("test.test_import.data.lazy_imports.basic2", sys.modules) + def test_dunder_lazy_import_invalid_arguments(self): + """__lazy_import__ should reject invalid arguments.""" + for invalid_name in (b"", 123, None): + with self.assertRaises(TypeError): + __lazy_import__(invalid_name) + + with self.assertRaises(ValueError): + __lazy_import__("sys", level=-1) + def test_dunder_lazy_import_builtins(self): """__lazy_import__ should use module's __builtins__ for __import__.""" from test.test_import.data.lazy_imports import dunder_lazy_import_builtins diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-02-21-09-47-45.gh-issue-145058.e-RBw-.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-21-09-47-45.gh-issue-145058.e-RBw-.rst new file mode 100644 index 00000000000..05eb296f96e --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-02-21-09-47-45.gh-issue-145058.e-RBw-.rst @@ -0,0 +1,2 @@ +Fix a crash when :func:`!__lazy_import__` is passed a non-string argument, +by raising an :exc:`TypeError` instead. diff --git a/Python/import.c b/Python/import.c index c20c55727d2..4c234a4a704 100644 --- a/Python/import.c +++ b/Python/import.c @@ -4468,6 +4468,17 @@ _PyImport_LazyImportModuleLevelObject(PyThreadState *tstate, PyObject *globals, PyObject *locals, PyObject *fromlist, int level) { + assert(name != NULL); + if (!PyUnicode_Check(name)) { + _PyErr_Format(tstate, PyExc_TypeError, + "module name must be a string, got %T", name); + return NULL; + } + if (level < 0) { + _PyErr_SetString(tstate, PyExc_ValueError, "level must be >= 0"); + return NULL; + } + PyObject *abs_name = get_abs_name(tstate, name, globals, level); if (abs_name == NULL) { return NULL;