diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2017-06-27 18:08:58 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-06-27 18:08:58 (GMT) |
commit | 0edffa3073b551ffeca34952529e7b292f1bd350 (patch) | |
tree | dcbf750061bcbe9da3ae9401292185b44490bb4b | |
parent | 35d2ca2b94a6ff29e763ddb7727166f0592edfa2 (diff) | |
download | cpython-0edffa3073b551ffeca34952529e7b292f1bd350.zip cpython-0edffa3073b551ffeca34952529e7b292f1bd350.tar.gz cpython-0edffa3073b551ffeca34952529e7b292f1bd350.tar.bz2 |
[3.6] bpo-30708: Check for null characters in PyUnicode_AsWideCharString(). (GH-2285) (#2443)
Raise a ValueError if the second argument is NULL and the wchar_t\*
string contains null characters..
(cherry picked from commit e613e6add5f07ff6aad5802924596b631b707d2a)
-rw-r--r-- | Include/unicodeobject.h | 6 | ||||
-rw-r--r-- | Lib/ctypes/test/test_slicing.py | 4 | ||||
-rw-r--r-- | Modules/_ctypes/callproc.c | 2 | ||||
-rw-r--r-- | Modules/_ctypes/cfield.c | 2 | ||||
-rw-r--r-- | Modules/_cursesmodule.c | 2 | ||||
-rw-r--r-- | Modules/_io/winconsoleio.c | 11 | ||||
-rw-r--r-- | Modules/_localemodule.c | 4 | ||||
-rw-r--r-- | Modules/_tkinter.c | 2 | ||||
-rw-r--r-- | Modules/overlapped.c | 2 | ||||
-rw-r--r-- | Modules/timemodule.c | 2 | ||||
-rw-r--r-- | Objects/unicodeobject.c | 31 | ||||
-rw-r--r-- | PC/winsound.c | 2 |
12 files changed, 50 insertions, 20 deletions
diff --git a/Include/unicodeobject.h b/Include/unicodeobject.h index 5b87718..cec2b7f 100644 --- a/Include/unicodeobject.h +++ b/Include/unicodeobject.h @@ -1063,6 +1063,12 @@ PyAPI_FUNC(wchar_t*) PyUnicode_AsWideCharString( ); #ifndef Py_LIMITED_API +/* Similar to PyUnicode_AsWideCharString(unicode, NULL), but check if + the string contains null characters. */ +PyAPI_FUNC(wchar_t*) _PyUnicode_AsWideCharString( + PyObject *unicode /* Unicode object */ + ); + PyAPI_FUNC(void*) _PyUnicode_AsKind(PyObject *s, unsigned int kind); #endif diff --git a/Lib/ctypes/test/test_slicing.py b/Lib/ctypes/test/test_slicing.py index 240dc0c..a3932f1 100644 --- a/Lib/ctypes/test/test_slicing.py +++ b/Lib/ctypes/test/test_slicing.py @@ -134,7 +134,7 @@ class SlicesTestCase(unittest.TestCase): dll.my_wcsdup.restype = POINTER(c_wchar) dll.my_wcsdup.argtypes = POINTER(c_wchar), dll.my_free.restype = None - res = dll.my_wcsdup(s) + res = dll.my_wcsdup(s[:-1]) self.assertEqual(res[:len(s)], s) self.assertEqual(res[:len(s):], s) self.assertEqual(res[len(s)-1:-1:-1], s[::-1]) @@ -153,7 +153,7 @@ class SlicesTestCase(unittest.TestCase): dll.my_wcsdup.restype = POINTER(c_long) else: self.skipTest('Pointers to c_wchar are not supported') - res = dll.my_wcsdup(s) + res = dll.my_wcsdup(s[:-1]) tmpl = list(range(ord("a"), ord("z")+1)) self.assertEqual(res[:len(s)-1], tmpl) self.assertEqual(res[:len(s)-1:], tmpl) diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index 7d542fb..358f287 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -668,7 +668,7 @@ static int ConvParam(PyObject *obj, Py_ssize_t index, struct argument *pa) #ifdef CTYPES_UNICODE if (PyUnicode_Check(obj)) { pa->ffi_type = &ffi_type_pointer; - pa->value.p = PyUnicode_AsWideCharString(obj, NULL); + pa->value.p = _PyUnicode_AsWideCharString(obj); if (pa->value.p == NULL) return -1; pa->keep = PyCapsule_New(pa->value.p, CTYPES_CAPSULE_NAME_PYMEM, pymem_destructor); diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c index a43585f..113a815 100644 --- a/Modules/_ctypes/cfield.c +++ b/Modules/_ctypes/cfield.c @@ -1372,7 +1372,7 @@ Z_set(void *ptr, PyObject *value, Py_ssize_t size) /* We must create a wchar_t* buffer from the unicode object, and keep it alive */ - buffer = PyUnicode_AsWideCharString(value, NULL); + buffer = _PyUnicode_AsWideCharString(value); if (!buffer) return NULL; keep = PyCapsule_New(buffer, CTYPES_CFIELD_CAPSULE_NAME_PYMEM, pymem_destructor); diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c index d88d06e..41b831e 100644 --- a/Modules/_cursesmodule.c +++ b/Modules/_cursesmodule.c @@ -345,7 +345,7 @@ PyCurses_ConvertToString(PyCursesWindowObject *win, PyObject *obj, if (PyUnicode_Check(obj)) { #ifdef HAVE_NCURSESW assert (wstr != NULL); - *wstr = PyUnicode_AsWideCharString(obj, NULL); + *wstr = _PyUnicode_AsWideCharString(obj); if (*wstr == NULL) return 0; return 2; diff --git a/Modules/_io/winconsoleio.c b/Modules/_io/winconsoleio.c index 94dfe3e..346c386 100644 --- a/Modules/_io/winconsoleio.c +++ b/Modules/_io/winconsoleio.c @@ -79,7 +79,7 @@ char _PyIO_get_console_type(PyObject *path_or_fd) { PyErr_Clear(); return '\0'; } - decoded_wstr = PyUnicode_AsWideCharString(decoded, NULL); + decoded_wstr = _PyUnicode_AsWideCharString(decoded); Py_CLEAR(decoded); if (!decoded_wstr) { PyErr_Clear(); @@ -311,8 +311,7 @@ _io__WindowsConsoleIO___init___impl(winconsoleio *self, PyObject *nameobj, if (!d) return -1; - Py_ssize_t length; - name = PyUnicode_AsWideCharString(decodedname, &length); + name = _PyUnicode_AsWideCharString(decodedname); console_type = _PyIO_get_console_type(decodedname); Py_CLEAR(decodedname); if (name == NULL) @@ -322,12 +321,6 @@ _io__WindowsConsoleIO___init___impl(winconsoleio *self, PyObject *nameobj, "Cannot open non-console file"); return -1; } - - if (wcslen(name) != length) { - PyMem_Free(name); - PyErr_SetString(PyExc_ValueError, "embedded null character"); - return -1; - } } s = mode; diff --git a/Modules/_localemodule.c b/Modules/_localemodule.c index feb3802..0c7c3cd 100644 --- a/Modules/_localemodule.c +++ b/Modules/_localemodule.c @@ -215,10 +215,10 @@ PyLocale_strcoll(PyObject* self, PyObject* args) if (!PyArg_ParseTuple(args, "UU:strcoll", &os1, &os2)) return NULL; /* Convert the unicode strings to wchar[]. */ - ws1 = PyUnicode_AsWideCharString(os1, NULL); + ws1 = _PyUnicode_AsWideCharString(os1); if (ws1 == NULL) goto done; - ws2 = PyUnicode_AsWideCharString(os2, NULL); + ws2 = _PyUnicode_AsWideCharString(os2); if (ws2 == NULL) goto done; /* Collate the strings. */ diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index 3e96aa0..4a1324c 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -3615,7 +3615,7 @@ PyInit__tkinter(void) return NULL; } if (str_path != NULL) { - wcs_path = PyUnicode_AsWideCharString(str_path, NULL); + wcs_path = _PyUnicode_AsWideCharString(str_path); if (wcs_path == NULL) { return NULL; } diff --git a/Modules/overlapped.c b/Modules/overlapped.c index 0aa8657..17581e0 100644 --- a/Modules/overlapped.c +++ b/Modules/overlapped.c @@ -1151,7 +1151,7 @@ ConnectPipe(OverlappedObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "U", &AddressObj)) return NULL; - Address = PyUnicode_AsWideCharString(AddressObj, NULL); + Address = _PyUnicode_AsWideCharString(AddressObj); if (Address == NULL) return NULL; diff --git a/Modules/timemodule.c b/Modules/timemodule.c index 328b84f..d6c34b9 100644 --- a/Modules/timemodule.c +++ b/Modules/timemodule.c @@ -607,7 +607,7 @@ time_strftime(PyObject *self, PyObject *args) buf.tm_isdst = 1; #ifdef HAVE_WCSFTIME - format = PyUnicode_AsWideCharString(format_arg, NULL); + format = _PyUnicode_AsWideCharString(format_arg); if (format == NULL) return NULL; fmt = format; diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 4e0c663..3767064 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -3017,6 +3017,37 @@ PyUnicode_AsWideCharString(PyObject *unicode, return buffer; } +wchar_t* +_PyUnicode_AsWideCharString(PyObject *unicode) +{ + const wchar_t *wstr; + wchar_t *buffer; + Py_ssize_t buflen; + + if (unicode == NULL) { + PyErr_BadInternalCall(); + return NULL; + } + + wstr = PyUnicode_AsUnicodeAndSize(unicode, &buflen); + if (wstr == NULL) { + return NULL; + } + if (wcslen(wstr) != (size_t)buflen) { + PyErr_SetString(PyExc_ValueError, + "embedded null character"); + return NULL; + } + + buffer = PyMem_NEW(wchar_t, buflen + 1); + if (buffer == NULL) { + PyErr_NoMemory(); + return NULL; + } + memcpy(buffer, wstr, (buflen + 1) * sizeof(wchar_t)); + return buffer; +} + #endif /* HAVE_WCHAR_H */ PyObject * diff --git a/PC/winsound.c b/PC/winsound.c index 7feebcb..0d3f045 100644 --- a/PC/winsound.c +++ b/PC/winsound.c @@ -101,7 +101,7 @@ winsound_PlaySound_impl(PyObject *module, PyObject *sound, int flags) Py_TYPE(sound)->tp_name); return NULL; } - wsound = PyUnicode_AsWideCharString(sound, NULL); + wsound = _PyUnicode_AsWideCharString(sound); if (wsound == NULL) { return NULL; } |