From 11b707616800e08891f6b610be90033acda8ffd0 Mon Sep 17 00:00:00 2001 From: Xiaojun Bi Date: Fri, 18 Apr 2014 10:52:15 -0700 Subject: [PATCH] Fix a bug for counting code points in WordComposer.java This bug threw an ArrayIndexOutOfBoundsException when the word length is 49 (maxSize + 1) when calling StringUtils.copyCodePointsAndReturnCodePointCount(...) in the same function. This bug is discovered by running SKETCH. The intent is to count the code points from index 0 to index i (included). The original code only counted the code points from index 0 to index (i-1). Bug: 13969542 Change-Id: Idbf596aba2379ba552dbe580c83c42044d505aaf --- .../inputmethod/latin/BinaryDictionary.java | 2 +- .../android/inputmethod/latin/WordComposer.java | 17 ++++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/java/src/com/android/inputmethod/latin/BinaryDictionary.java b/java/src/com/android/inputmethod/latin/BinaryDictionary.java index 5e36d9703..88174ba83 100644 --- a/java/src/com/android/inputmethod/latin/BinaryDictionary.java +++ b/java/src/com/android/inputmethod/latin/BinaryDictionary.java @@ -260,7 +260,7 @@ public final class BinaryDictionary extends Dictionary { final int inputSize; if (!isGesture) { inputSize = composer.copyCodePointsExceptTrailingSingleQuotesAndReturnCodePointCount( - mInputCodePoints, MAX_WORD_LENGTH); + mInputCodePoints); if (inputSize < 0) { return null; } diff --git a/java/src/com/android/inputmethod/latin/WordComposer.java b/java/src/com/android/inputmethod/latin/WordComposer.java index 1268e5aac..d755195f2 100644 --- a/java/src/com/android/inputmethod/latin/WordComposer.java +++ b/java/src/com/android/inputmethod/latin/WordComposer.java @@ -129,22 +129,25 @@ public final class WordComposer { * -1 is returned. * * @param destination the array of ints. - * @param maxSize the size of the array. * @return the number of copied code points. */ public int copyCodePointsExceptTrailingSingleQuotesAndReturnCodePointCount( - final int[] destination, final int maxSize) { - final int i = mTypedWordCache.length() - 1 - trailingSingleQuotesCount(); - if (i < 0) { + final int[] destination) { + // lastIndex is exclusive + final int lastIndex = mTypedWordCache.length() - trailingSingleQuotesCount(); + if (lastIndex <= 0) { // The string is empty or contains only single quotes. return 0; } - final int codePointSize = Character.codePointCount(mTypedWordCache, 0, i); - if (codePointSize > maxSize) { + + // The following function counts the number of code points in the text range which begins + // at index 0 and extends to the character at lastIndex. + final int codePointSize = Character.codePointCount(mTypedWordCache, 0, lastIndex); + if (codePointSize > destination.length) { return -1; } return StringUtils.copyCodePointsAndReturnCodePointCount(destination, mTypedWordCache, 0, - i + 1, true /* downCase */); + lastIndex, true /* downCase */); } public boolean isSingleLetter() {