summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Victor Chang <vichang@google.com> 2018-11-27 12:40:23 +0000
committer Victor Chang <vichang@google.com> 2018-11-28 18:15:57 +0000
commitc1463eccd4af9b52aa387c6475d29fcafe2228b7 (patch)
tree2eb730cdf6dd68e104d07de38a8d418b0996ad09
parentfb9335b8867eeeb6b26c6ad672dfa5a88b3f153f (diff)
Fix max directionality in AndroidCharacter.getDirectionalities
U_CHAR_DIRECTION_COUNT has been used for boundary check for conversion of directionality between ICU and Libcore. However, the max directionality in ICU has been incresed from 18 to 22 since Unicode 6.3 https://github.com/unicode-org/icu/commit/2982958b06e#diff-c46912f650de1f607d39dd8d81fb4b57 But the max directionality has not been chagned in libcore, and thus it will return undefined value in directionality_map. Also, this commit also replaces @Deprecated API U_EA_COUNT by u_getIntPropertyMaxValue(UCHAR_EAST_ASIAN_WIDTH). Bug: 120073244 Bug: 117094880 Test: AndroidCharacterTest Change-Id: I39918bdd4b06d0f1e95ad923594a28a0afc82b9e
-rw-r--r--core/jni/android_text_AndroidCharacter.cpp14
-rw-r--r--core/tests/coretests/src/android/text/AndroidCharacterTest.java77
2 files changed, 85 insertions, 6 deletions
diff --git a/core/jni/android_text_AndroidCharacter.cpp b/core/jni/android_text_AndroidCharacter.cpp
index 8885aac49064..9bba13a6930e 100644
--- a/core/jni/android_text_AndroidCharacter.cpp
+++ b/core/jni/android_text_AndroidCharacter.cpp
@@ -25,9 +25,10 @@
#include "unicode/uchar.h"
#define PROPERTY_UNDEFINED (-1)
+#define JAVA_LANG_CHARACTER_MAX_DIRECTIONALITY 18
// ICU => JDK mapping
-static int directionality_map[U_CHAR_DIRECTION_COUNT] = {
+static int directionality_map[JAVA_LANG_CHARACTER_MAX_DIRECTIONALITY + 1] = {
0, // U_LEFT_TO_RIGHT (0) => DIRECTIONALITY_LEFT_TO_RIGHT (0)
1, // U_RIGHT_TO_LEFT (1) => DIRECTIONALITY_RIGHT_TO_LEFT (1)
3, // U_EUROPEAN_NUMBER (2) => DIRECTIONALITY_EUROPEAN_NUMBER (3)
@@ -75,7 +76,7 @@ static void getDirectionalities(JNIEnv* env, jobject obj, jcharArray srcArray,
int c = 0x00010000 + ((src[i] - 0xD800) << 10) +
(src[i + 1] & 0x3FF);
int dir = u_charDirection(c);
- if (dir < 0 || dir >= U_CHAR_DIRECTION_COUNT)
+ if (dir < 0 || dir > JAVA_LANG_CHARACTER_MAX_DIRECTIONALITY)
dir = PROPERTY_UNDEFINED;
else
dir = directionality_map[dir];
@@ -85,7 +86,7 @@ static void getDirectionalities(JNIEnv* env, jobject obj, jcharArray srcArray,
} else {
int c = src[i];
int dir = u_charDirection(c);
- if (dir < 0 || dir >= U_CHAR_DIRECTION_COUNT)
+ if (dir < 0 || dir > JAVA_LANG_CHARACTER_MAX_DIRECTIONALITY)
dest[i] = PROPERTY_UNDEFINED;
else
dest[i] = directionality_map[dir];
@@ -96,7 +97,7 @@ static void getDirectionalities(JNIEnv* env, jobject obj, jcharArray srcArray,
static jint getEastAsianWidth(JNIEnv* env, jobject obj, jchar input)
{
int width = u_getIntPropertyValue(input, UCHAR_EAST_ASIAN_WIDTH);
- if (width < 0 || width >= U_EA_COUNT)
+ if (width < 0 || width > u_getIntPropertyMaxValue(UCHAR_EAST_ASIAN_WIDTH))
width = PROPERTY_UNDEFINED;
return width;
@@ -121,6 +122,7 @@ static void getEastAsianWidths(JNIEnv* env, jobject obj, jcharArray srcArray,
return;
}
+ int maxWidth = u_getIntPropertyMaxValue(UCHAR_EAST_ASIAN_WIDTH);
for (int i = 0; i < count; i++) {
const int srci = start + i;
if (src[srci] >= 0xD800 && src[srci] <= 0xDBFF &&
@@ -129,7 +131,7 @@ static void getEastAsianWidths(JNIEnv* env, jobject obj, jcharArray srcArray,
int c = 0x00010000 + ((src[srci] - 0xD800) << 10) +
(src[srci + 1] & 0x3FF);
int width = u_getIntPropertyValue(c, UCHAR_EAST_ASIAN_WIDTH);
- if (width < 0 || width >= U_EA_COUNT)
+ if (width < 0 || width > maxWidth)
width = PROPERTY_UNDEFINED;
dest[i++] = width;
@@ -137,7 +139,7 @@ static void getEastAsianWidths(JNIEnv* env, jobject obj, jcharArray srcArray,
} else {
int c = src[srci];
int width = u_getIntPropertyValue(c, UCHAR_EAST_ASIAN_WIDTH);
- if (width < 0 || width >= U_EA_COUNT)
+ if (width < 0 || width > maxWidth)
width = PROPERTY_UNDEFINED;
dest[i] = width;
diff --git a/core/tests/coretests/src/android/text/AndroidCharacterTest.java b/core/tests/coretests/src/android/text/AndroidCharacterTest.java
new file mode 100644
index 000000000000..d976adb14ef3
--- /dev/null
+++ b/core/tests/coretests/src/android/text/AndroidCharacterTest.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,d
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text;
+
+import static org.junit.Assert.assertArrayEquals;
+
+import android.platform.test.annotations.Presubmit;
+import android.support.test.filters.SmallTest;
+
+import org.junit.Test;
+
+@Presubmit
+@SmallTest
+public class AndroidCharacterTest {
+
+ @Test
+ public void testGetDirectionalities_nonSupplementaryCharacters() {
+ int size = Character.MAX_VALUE + 1
+ - (Character.MAX_SURROGATE - Character.MIN_SURROGATE + 1);
+ char[] chars = new char[size];
+ byte[] java_lang_results = new byte[size];
+ int index = 0;
+ for (int cp = 0; cp <= Character.MAX_VALUE; cp++) {
+ // Exempt unassigned code point due to b/120074586
+ if (Character.getType(cp) != Character.UNASSIGNED) {
+ if (cp < Character.MIN_SURROGATE || cp > Character.MAX_SURROGATE) {
+ chars[index] = (char) cp;
+ java_lang_results[index] = Character.getDirectionality(cp);
+ index++;
+ }
+ }
+ }
+
+ byte[] android_text_results = new byte[size];
+ AndroidCharacter.getDirectionalities(chars, android_text_results, index);
+ assertArrayEquals(java_lang_results, android_text_results);
+ }
+
+ @Test
+ public void testGetDirectionalities_supplementaryCharacters() {
+ int maxNumberOfChars = Character.MAX_CODE_POINT - Character.MIN_SUPPLEMENTARY_CODE_POINT
+ + 1;
+ int size = maxNumberOfChars * 2;
+ char[] chars = new char[size];
+ byte[] java_lang_results = new byte[size];
+ int index = 0;
+ for (int cp = Character.MIN_SUPPLEMENTARY_CODE_POINT; cp <= Character.MAX_CODE_POINT;
+ cp++) {
+ // Exempt unassigned code point due to b/120074586
+ if (Character.getType(cp) != Character.UNASSIGNED) {
+ chars[index] = Character.highSurrogate(cp);
+ chars[index + 1] = Character.lowSurrogate(cp);
+ java_lang_results[index] = java_lang_results[index + 1] = Character
+ .getDirectionality(cp);
+ index += 2;
+ }
+ }
+
+ byte[] android_text_results = new byte[size];
+ AndroidCharacter.getDirectionalities(chars, android_text_results, index);
+ assertArrayEquals(java_lang_results, android_text_results);
+ }
+}