gh-127208: Reject null character in _imp.create_dynamic() (#127400)
_imp.create_dynamic() now rejects embedded null characters in the
path and in the module name.
Backport also the _PyUnicode_AsUTF8NoNUL() function.
(cherry picked from commit
b14fdadc6c620875a20b7ccc3c9b069e85d8557a)
extern void _PyUnicode_ClearInterned(PyInterpreterState *interp);
+// Like PyUnicode_AsUTF8(), but check for embedded null characters.
+extern const char* _PyUnicode_AsUTF8NoNUL(PyObject *);
+
#ifdef __cplusplus
}
self.assertIn("Frozen object named 'x' is invalid",
str(cm.exception))
+ 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):
return PyUnicode_AsUTF8AndSize(unicode, NULL);
}
+const char *
+_PyUnicode_AsUTF8NoNUL(PyObject *unicode)
+{
+ Py_ssize_t size;
+ const char *s = PyUnicode_AsUTF8AndSize(unicode, &size);
+ if (s && strlen(s) != (size_t)size) {
+ PyErr_SetString(PyExc_ValueError, "embedded null character");
+ return NULL;
+ }
+ return s;
+}
+
/*
PyUnicode_GetSize() has been deprecated since Python 3.3
because it returned length of Py_UNICODE.
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;