]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-145058: Add input validation to `_PyImport_LazyImportModuleLevelObject` (#145068)
authorStan Ulbrych <89152624+StanFromIreland@users.noreply.github.com>
Sat, 21 Feb 2026 12:52:40 +0000 (12:52 +0000)
committerGitHub <noreply@github.com>
Sat, 21 Feb 2026 12:52:40 +0000 (12:52 +0000)
Lib/test/test_import/test_lazy_imports.py
Misc/NEWS.d/next/Core_and_Builtins/2026-02-21-09-47-45.gh-issue-145058.e-RBw-.rst [new file with mode: 0644]
Python/import.c

index a4c9c14ae2b5f86f7aa820c052938e3b3a99e31b..dc185c070acc624413fbd4489b21ec5ffb2c406d 100644 (file)
@@ -393,6 +393,15 @@ class DunderLazyImportTests(unittest.TestCase):
         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 (file)
index 0000000..05eb296
--- /dev/null
@@ -0,0 +1,2 @@
+Fix a crash when :func:`!__lazy_import__` is passed a non-string argument,
+by raising an :exc:`TypeError` instead.
index c20c55727d2f94c41bac47cad1a6015bb7897022..4c234a4a70437cfed28580de372498b40d4380b4 100644 (file)
@@ -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;