Handle integer overflow in BaseInputConnection
When IME tries to load input context with a large range like [Integer.MAX_VALUE, Integer.MAX_VALUE], app might crash as current implementation can't handle integer overflow well. Fix the issue by guarding the range of the text after the cursor. Test: BaseInputConnectionTest BUG: 279670566 Fix: 279670566 Change-Id: I5e3df4f2288896cbd21f6c1a59b7e315c60029c4
This commit is contained in:
@@ -622,15 +622,11 @@ public class BaseInputConnection implements InputConnection {
|
||||
if (b < 0) {
|
||||
b = 0;
|
||||
}
|
||||
|
||||
if (b + length > content.length()) {
|
||||
length = content.length() - b;
|
||||
}
|
||||
|
||||
int end = (int) Math.min((long) b + length, content.length());
|
||||
if ((flags&GET_TEXT_WITH_STYLES) != 0) {
|
||||
return content.subSequence(b, b + length);
|
||||
return content.subSequence(b, end);
|
||||
}
|
||||
return TextUtils.substring(content, b, b + length);
|
||||
return TextUtils.substring(content, b, end);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -666,13 +662,9 @@ public class BaseInputConnection implements InputConnection {
|
||||
selEnd = tmp;
|
||||
}
|
||||
|
||||
int contentLength = content.length();
|
||||
int startPos = selStart - beforeLength;
|
||||
int endPos = selEnd + afterLength;
|
||||
|
||||
// Guards the start and end pos within range [0, contentLength].
|
||||
startPos = Math.max(0, startPos);
|
||||
endPos = Math.min(contentLength, endPos);
|
||||
int startPos = Math.max(0, selStart - beforeLength);
|
||||
int endPos = (int) Math.min((long) selEnd + afterLength, content.length());
|
||||
|
||||
CharSequence surroundingText;
|
||||
if ((flags & GET_TEXT_WITH_STYLES) != 0) {
|
||||
|
||||
@@ -549,6 +549,14 @@ public class BaseInputConnectionTest {
|
||||
.isEqualTo(new SurroundingText("456", 0, 3, -1)))
|
||||
.isTrue();
|
||||
|
||||
verifyContentEquals(mBaseInputConnection.getTextBeforeCursor(Integer.MAX_VALUE, 0), "123");
|
||||
verifyContentEquals(mBaseInputConnection.getTextAfterCursor(Integer.MAX_VALUE, 0), "789");
|
||||
assertThat(
|
||||
mBaseInputConnection
|
||||
.getSurroundingText(Integer.MAX_VALUE, Integer.MAX_VALUE, 0)
|
||||
.isEqualTo(new SurroundingText("123456789", 3, 6, -1)))
|
||||
.isTrue();
|
||||
|
||||
int cursorCapsMode =
|
||||
TextUtils.getCapsMode(
|
||||
"123456789",
|
||||
@@ -617,6 +625,45 @@ public class BaseInputConnectionTest {
|
||||
verifyTextSnapshotContentEquals(mBaseInputConnection.takeSnapshot(), expectedTextSnapshot);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetText_emptyText() {
|
||||
// ""
|
||||
prepareContent("", 0, 0, -1, -1);
|
||||
|
||||
verifyContentEquals(mBaseInputConnection.getTextBeforeCursor(1, 0), "");
|
||||
verifyContentEquals(mBaseInputConnection.getTextAfterCursor(1, 0), "");
|
||||
assertThat(mBaseInputConnection.getSelectedText(0)).isNull();
|
||||
|
||||
// This falls back to default implementation in {@code InputConnection}, which always return
|
||||
// -1 for offset.
|
||||
assertThat(
|
||||
mBaseInputConnection
|
||||
.getSurroundingText(1, 1, 0)
|
||||
.isEqualTo(new SurroundingText("", 0, 0, -1)))
|
||||
.isTrue();
|
||||
|
||||
verifyContentEquals(mBaseInputConnection.getTextBeforeCursor(0, 0), "");
|
||||
verifyContentEquals(mBaseInputConnection.getTextAfterCursor(0, 0), "");
|
||||
assertThat(mBaseInputConnection.getSelectedText(0)).isNull();
|
||||
// This falls back to default implementation in {@code InputConnection}, which always return
|
||||
// -1 for offset.
|
||||
assertThat(
|
||||
mBaseInputConnection
|
||||
.getSurroundingText(0, 0, 0)
|
||||
.isEqualTo(new SurroundingText("", 0, 0, -1)))
|
||||
.isTrue();
|
||||
|
||||
verifyContentEquals(mBaseInputConnection.getTextBeforeCursor(Integer.MAX_VALUE, 0), "");
|
||||
verifyContentEquals(mBaseInputConnection.getTextAfterCursor(Integer.MAX_VALUE, 0), "");
|
||||
assertThat(mBaseInputConnection.getSelectedText(0)).isNull();
|
||||
assertThat(
|
||||
mBaseInputConnection
|
||||
.getSurroundingText(Integer.MAX_VALUE, Integer.MAX_VALUE, 0)
|
||||
.isEqualTo(new SurroundingText("", 0, 0, -1)))
|
||||
.isTrue();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testReplaceText_toEditorWithoutSelectionAndComposing() {
|
||||
// before replace: "|"
|
||||
|
||||
Reference in New Issue
Block a user