Author: Armin Rigo <ar...@tunes.org>
Branch: 
Changeset: r2972:0300a91f7fb4
Date: 2017-06-04 14:24 +0200
http://bitbucket.org/cffi/cffi/changeset/0300a91f7fb4/

Log:    Detect and complain when trying to convert a char32_t to unicode if
        the unicode uses 16-bit chars and the original char32_t is out of
        range even for surrogates

diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -1390,10 +1390,9 @@
             if (n != ct->ct_length)
                 n++;
             if (ctitem->ct_size == 4)
-                _my_PyUnicode_AsChar32(init, (cffi_char32_t *)data, n);
+                return _my_PyUnicode_AsChar32(init, (cffi_char32_t *)data, n);
             else
-                _my_PyUnicode_AsChar16(init, (cffi_char16_t *)data, n);
-            return 0;
+                return _my_PyUnicode_AsChar16(init, (cffi_char16_t *)data, n);
         }
     }
     else {
diff --git a/c/wchar_helper.h b/c/wchar_helper.h
--- a/c/wchar_helper.h
+++ b/c/wchar_helper.h
@@ -195,9 +195,9 @@
     return result;
 }
 
-static void _my_PyUnicode_AsChar16(PyObject *unicode,
-                                   cffi_char16_t *result,
-                                   Py_ssize_t resultlen)
+static int _my_PyUnicode_AsChar16(PyObject *unicode,
+                                  cffi_char16_t *result,
+                                  Py_ssize_t resultlen)
 {
     Py_ssize_t len = PyUnicode_GET_SIZE(unicode);
     Py_UNICODE *u = PyUnicode_AS_UNICODE(unicode);
@@ -208,9 +208,12 @@
 #else
         cffi_char32_t ordinal = u[i];
         if (ordinal > 0xFFFF) {
-            /* NB. like CPython, ignore the problem of unicode string objects
-             * containing characters greater than sys.maxunicode.  It is
-             * easier to not add exception handling here */
+            if (ordinal > 0x10FFFF) {
+                PyErr_Format(PyExc_ValueError,
+                             "unicode character out of range for "
+                             "conversion to char16_t: 0x%x", (int)ordinal);
+                return -1;
+            }
             ordinal -= 0x10000;
             *result++ = 0xD800 | (ordinal >> 10);
             *result++ = 0xDC00 | (ordinal & 0x3FF);
@@ -219,11 +222,12 @@
 #endif
         *result++ = ordinal;
     }
+    return 0;
 }
 
-static void _my_PyUnicode_AsChar32(PyObject *unicode,
-                                   cffi_char32_t *result,
-                                   Py_ssize_t resultlen)
+static int _my_PyUnicode_AsChar32(PyObject *unicode,
+                                  cffi_char32_t *result,
+                                  Py_ssize_t resultlen)
 {
     Py_UNICODE *u = PyUnicode_AS_UNICODE(unicode);
     Py_ssize_t i;
@@ -238,4 +242,5 @@
         result[i] = ordinal;
         u++;
     }
+    return 0;
 }
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to