Fix: StringIndexOutOfBoundsException.

Bug: 14985751
Change-Id: I9df2f737555ab02e24e0fbd231a97c1eec26bc57
main
Keisuke Kuroyanagi 2014-05-16 15:32:12 +09:00
parent d94567d963
commit 34873a66f0
5 changed files with 26 additions and 14 deletions

View File

@ -94,8 +94,8 @@ public final class Suggest {
final boolean blockOffensiveWords, final boolean isCorrectionEnabled,
final int[] additionalFeaturesOptions, final int sequenceNumber,
final OnGetSuggestedWordsCallback callback) {
final int trailingSingleQuotesCount = wordComposer.trailingSingleQuotesCount();
final String typedWord = wordComposer.getTypedWord();
final int trailingSingleQuotesCount = StringUtils.getTrailingSingleQuotesCount(typedWord);
final String consideredWord = trailingSingleQuotesCount > 0
? typedWord.substring(0, typedWord.length() - trailingSingleQuotesCount)
: typedWord;

View File

@ -149,7 +149,8 @@ public final class WordComposer {
public int copyCodePointsExceptTrailingSingleQuotesAndReturnCodePointCount(
final int[] destination) {
// lastIndex is exclusive
final int lastIndex = mTypedWordCache.length() - trailingSingleQuotesCount();
final int lastIndex = mTypedWordCache.length()
- StringUtils.getTrailingSingleQuotesCount(mTypedWordCache);
if (lastIndex <= 0) {
// The string is empty or contains only single quotes.
return 0;
@ -331,15 +332,6 @@ public final class WordComposer {
return mIsFirstCharCapitalized;
}
public int trailingSingleQuotesCount() {
final int lastIndex = mTypedWordCache.length() - 1;
int i = lastIndex;
while (i >= 0 && mTypedWordCache.charAt(i) == Constants.CODE_SINGLE_QUOTE) {
--i;
}
return lastIndex - i;
}
/**
* Whether or not all of the user typed chars are upper case
* @return true if all user typed chars are upper case, false otherwise

View File

@ -86,9 +86,10 @@ public class DistracterFilter {
coordinates = mKeyboard.getCoordinates(codePoints);
composer.setComposingWord(codePoints, coordinates, prevWord);
final int trailingSingleQuotesCount = composer.trailingSingleQuotesCount();
final String consideredWord = trailingSingleQuotesCount > 0 ? testedWord.substring(0,
testedWord.length() - trailingSingleQuotesCount) : testedWord;
final int trailingSingleQuotesCount = StringUtils.getTrailingSingleQuotesCount(testedWord);
final String consideredWord = trailingSingleQuotesCount > 0 ?
testedWord.substring(0, testedWord.length() - trailingSingleQuotesCount) :
testedWord;
final AsyncResultHolder<Boolean> holder = new AsyncResultHolder<Boolean>();
final OnGetSuggestedWordsCallback callback = new OnGetSuggestedWordsCallback() {
@Override

View File

@ -538,6 +538,15 @@ public final class StringUtils {
? casedText.codePointAt(0) : CODE_UNSPECIFIED;
}
public static int getTrailingSingleQuotesCount(final CharSequence charSequence) {
final int lastIndex = charSequence.length() - 1;
int i = lastIndex;
while (i >= 0 && charSequence.charAt(i) == Constants.CODE_SINGLE_QUOTE) {
--i;
}
return lastIndex - i;
}
@UsedForTesting
public static class Stringizer<E> {
public String stringize(final E element) {

View File

@ -372,4 +372,14 @@ public class StringAndJsonUtilsTests extends AndroidTestCase {
assertTrue("copyCodePointsAndReturnCodePointCount throws when array is too small",
exceptionHappened);
}
public void testGetTrailingSingleQuotesCount() {
assertEquals(0, StringUtils.getTrailingSingleQuotesCount(""));
assertEquals(1, StringUtils.getTrailingSingleQuotesCount("'"));
assertEquals(5, StringUtils.getTrailingSingleQuotesCount("'''''"));
assertEquals(0, StringUtils.getTrailingSingleQuotesCount("a"));
assertEquals(0, StringUtils.getTrailingSingleQuotesCount("'this"));
assertEquals(1, StringUtils.getTrailingSingleQuotesCount("'word'"));
assertEquals(0, StringUtils.getTrailingSingleQuotesCount("I'm"));
}
}