Fix regression in CursorWindow.getString()
Bug: 5332296

NewStringUTF expects modified UTF-8, so it barfs on UTF-8 strings
that contain high codepoints.  Even though it results in an extra
copy being performed, first convert to UTF-16, then call NewString.

Change-Id: Idbfeb3cc2c4b731834e4482848dcac2fa33ec2d0
diff --git a/core/jni/android_database_CursorWindow.cpp b/core/jni/android_database_CursorWindow.cpp
index 7f5c0d4..fe1aca0 100644
--- a/core/jni/android_database_CursorWindow.cpp
+++ b/core/jni/android_database_CursorWindow.cpp
@@ -205,8 +205,14 @@
     if (type == FIELD_TYPE_STRING) {
         uint32_t size = fieldSlot->data.buffer.size;
 #if WINDOW_STORAGE_UTF8
-        return size > 1 ? env->NewStringUTF(window->getFieldSlotValueString(fieldSlot))
-                : gEmptyString;
+        if (size <= 1) {
+            return gEmptyString;
+        }
+        // Convert to UTF-16 here instead of calling NewStringUTF.  NewStringUTF
+        // doesn't like UTF-8 strings with high codepoints.  It actually expects
+        // Modified UTF-8 with encoded surrogate pairs.
+        String16 utf16(window->getFieldSlotValueString(fieldSlot), size - 1);
+        return env->NewString(reinterpret_cast<const jchar*>(utf16.string()), utf16.size());
 #else
         size_t chars = size / sizeof(char16_t);
         return chars ? env->NewString(reinterpret_cast<jchar*>(