summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2017-06-27 18:08:58 (GMT)
committerGitHub <noreply@github.com>2017-06-27 18:08:58 (GMT)
commit0edffa3073b551ffeca34952529e7b292f1bd350 (patch)
treedcbf750061bcbe9da3ae9401292185b44490bb4b
parent35d2ca2b94a6ff29e763ddb7727166f0592edfa2 (diff)
downloadcpython-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.h6
-rw-r--r--Lib/ctypes/test/test_slicing.py4
-rw-r--r--Modules/_ctypes/callproc.c2
-rw-r--r--Modules/_ctypes/cfield.c2
-rw-r--r--Modules/_cursesmodule.c2
-rw-r--r--Modules/_io/winconsoleio.c11
-rw-r--r--Modules/_localemodule.c4
-rw-r--r--Modules/_tkinter.c2
-rw-r--r--Modules/overlapped.c2
-rw-r--r--Modules/timemodule.c2
-rw-r--r--Objects/unicodeobject.c31
-rw-r--r--PC/winsound.c2
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;
}