]> granicus.if.org Git - python/commitdiff
[3.5] bpo-30708: Add private C API function _PyUnicode_AsWideCharString(). (GH-2285...
authorSerhiy Storchaka <storchaka@gmail.com>
Tue, 27 Jun 2017 18:52:10 +0000 (21:52 +0300)
committerGitHub <noreply@github.com>
Tue, 27 Jun 2017 18:52:10 +0000 (21:52 +0300)
And use it instead of PyUnicode_AsWideCharString() if appropriate.

_PyUnicode_AsWideCharString(unicode) is like PyUnicode_AsWideCharString(unicode, NULL), but
raises a ValueError if the wchar_t* string contains null characters.
(cherry picked from commit e613e6add5f07ff6aad5802924596b631b707d2a).
(cherry picked from commit 0edffa3073b551ffeca34952529e7b292f1bd350)

Include/unicodeobject.h
Lib/ctypes/test/test_slicing.py
Modules/_ctypes/callproc.c
Modules/_ctypes/cfield.c
Modules/_cursesmodule.c
Modules/_localemodule.c
Modules/_tkinter.c
Modules/overlapped.c
Modules/timemodule.c
Objects/unicodeobject.c

index 59dcf736b1b2b36eadce4ccb1284f1224f62eef6..0e44808050220ff10f99329d8763807b0fa9bee8 100644 (file)
@@ -1054,6 +1054,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
 
index 240dc0cdda2462eb9a980acb02b7594dfd0f19d6..a3932f176728aff0a0bb5a5412ba6a11499a4d5c 100644 (file)
@@ -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)
index abd3bc995d3e93c60e7aa3f4ae5d9bca6dce854f..873df8b7bdb88c0614b5522b7c12ca522edf19bc 100644 (file)
@@ -672,7 +672,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);
index d666be5d925fe2b1e2f82b11d0d1bee6c087e092..cb5c3ce8ea995c531a0b5427e66aeb823e8a9997 100644 (file)
@@ -1386,7 +1386,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);
index 896d40d38e40af3746886ee8bb560beaad709777..26d27317d03f2c0e84385666b621872b9e8fe0f0 100644 (file)
@@ -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;
index b1307ef26b2a8ee916f3c7f851ed439507f3720e..4ce71debcf8e4a801437ad57b1acf0527e53ca5f 100644 (file)
@@ -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. */
index 163c87f8b98360dc4b276283b65bf36d7f49f212..34f2d096b2741596d313ef1ca7190dd5d9d4d691 100644 (file)
@@ -3620,7 +3620,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;
                     }
index f85e5bc73641fb3c6341073a743552dc9a605815..3b31d11a7b151ae8b33e310eca1a6643b2356879 100644 (file)
@@ -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;
 
index d2caacdc6dd8dd968bf8f59d626630202b09f345..252fdcfb2c9300360a5a97a0f5b0994c860b15a0 100644 (file)
@@ -596,7 +596,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;
index d037d80b3d222e5f2042d7917dc92e22ebf1a294..64375da602d11f6d029052501a63dd7a4d30910a 100644 (file)
@@ -2839,6 +2839,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 *