mirror of
https://github.com/python/cpython.git
synced 2025-08-31 14:07:50 +00:00
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 b14fdadc6c
)
This commit is contained in:
parent
fc0564b365
commit
e7ab97862d
4 changed files with 33 additions and 3 deletions
|
@ -76,6 +76,9 @@ struct _Py_unicode_state {
|
||||||
|
|
||||||
extern void _PyUnicode_ClearInterned(PyInterpreterState *interp);
|
extern void _PyUnicode_ClearInterned(PyInterpreterState *interp);
|
||||||
|
|
||||||
|
// Like PyUnicode_AsUTF8(), but check for embedded null characters.
|
||||||
|
extern const char* _PyUnicode_AsUTF8NoNUL(PyObject *);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -787,6 +787,19 @@ class ImportTests(unittest.TestCase):
|
||||||
self.assertIn("Frozen object named 'x' is invalid",
|
self.assertIn("Frozen object named 'x' is invalid",
|
||||||
str(cm.exception))
|
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
|
@skip_if_dont_write_bytecode
|
||||||
class FilePermissionTests(unittest.TestCase):
|
class FilePermissionTests(unittest.TestCase):
|
||||||
|
|
|
@ -3991,6 +3991,18 @@ PyUnicode_AsUTF8(PyObject *unicode)
|
||||||
return PyUnicode_AsUTF8AndSize(unicode, NULL);
|
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
|
PyUnicode_GetSize() has been deprecated since Python 3.3
|
||||||
because it returned length of Py_UNICODE.
|
because it returned length of Py_UNICODE.
|
||||||
|
|
|
@ -917,12 +917,14 @@ extensions_lock_release(void)
|
||||||
static void *
|
static void *
|
||||||
hashtable_key_from_2_strings(PyObject *str1, PyObject *str2, const char sep)
|
hashtable_key_from_2_strings(PyObject *str1, PyObject *str2, const char sep)
|
||||||
{
|
{
|
||||||
Py_ssize_t str1_len, str2_len;
|
const char *str1_data = _PyUnicode_AsUTF8NoNUL(str1);
|
||||||
const char *str1_data = PyUnicode_AsUTF8AndSize(str1, &str1_len);
|
const char *str2_data = _PyUnicode_AsUTF8NoNUL(str2);
|
||||||
const char *str2_data = PyUnicode_AsUTF8AndSize(str2, &str2_len);
|
|
||||||
if (str1_data == NULL || str2_data == NULL) {
|
if (str1_data == NULL || str2_data == NULL) {
|
||||||
return 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. */
|
/* Make sure sep and the NULL byte won't cause an overflow. */
|
||||||
assert(SIZE_MAX - str1_len - str2_len > 2);
|
assert(SIZE_MAX - str1_len - str2_len > 2);
|
||||||
size_t size = str1_len + 1 + str2_len + 1;
|
size_t size = str1_len + 1 + str2_len + 1;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue