From c4a359dc426bcb1a5f16ef25b0e3110bb463bdad Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Fri, 29 Nov 2024 16:45:21 +0100 Subject: [PATCH] [3.13] gh-127208: Reject null character in _imp.create_dynamic() (GH-127400) (#127418) gh-127208: Reject null character in _imp.create_dynamic() (GH-127400) _imp.create_dynamic() now rejects embedded null characters in the path and in the module name. (cherry picked from commit b14fdadc6c620875a20b7ccc3c9b069e85d8557a) Co-authored-by: Victor Stinner --- Lib/test/test_import/__init__.py | 13 +++++++++++++ Python/import.c | 8 +++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py index 3f71a2bf3d9..9139d455f4a 100644 --- a/Lib/test/test_import/__init__.py +++ b/Lib/test/test_import/__init__.py @@ -1152,6 +1152,19 @@ except ImportError as e: stdout, stderr = popen.communicate() self.assertRegex(stdout, expected_error) + def test_create_dynamic_null(self): + with self.assertRaisesRegex(ValueError, 'embedded null character'): + class Spec: + name = "a\x00b" + origin = "abc" + _imp.create_dynamic(Spec()) + + with self.assertRaisesRegex(ValueError, 'embedded null character'): + class Spec2: + name = "abc" + origin = "a\x00b" + _imp.create_dynamic(Spec2()) + @skip_if_dont_write_bytecode class FilePermissionTests(unittest.TestCase): diff --git a/Python/import.c b/Python/import.c index 0f08e6dfc24..ea5a3e4a762 100644 --- a/Python/import.c +++ b/Python/import.c @@ -1155,12 +1155,14 @@ del_extensions_cache_value(struct extensions_cache_value *value) static void * hashtable_key_from_2_strings(PyObject *str1, PyObject *str2, const char sep) { - Py_ssize_t str1_len, str2_len; - const char *str1_data = PyUnicode_AsUTF8AndSize(str1, &str1_len); - const char *str2_data = PyUnicode_AsUTF8AndSize(str2, &str2_len); + const char *str1_data = _PyUnicode_AsUTF8NoNUL(str1); + const char *str2_data = _PyUnicode_AsUTF8NoNUL(str2); if (str1_data == NULL || str2_data == NULL) { return NULL; } + Py_ssize_t str1_len = strlen(str1_data); + Py_ssize_t str2_len = strlen(str2_data); + /* Make sure sep and the NULL byte won't cause an overflow. */ assert(SIZE_MAX - str1_len - str2_len > 2); size_t size = str1_len + 1 + str2_len + 1;