From 1a22db2927abf6860498ed4194947ba2d40d5ec7 Mon Sep 17 00:00:00 2001 From: Gilles Debunne Date: Sun, 20 Nov 2011 22:13:21 +0100 Subject: [PATCH] IOOB in text selection. Several issues here: 1. when selection has been set to size 0 (should not be possible, but see 2.), moving any of the selection handles will create an IOOB because we add/substract 1 with no test. Added min/max. 2. the text change detection, which stop selection mode, was done in handleTextChanged. We need to go deeper. Some methods (such as setText()) directly call the more atomic sendOnTextChange(). Moved the test down to this method. As a result, pressing the 'x' button in the QuickSearchBox correctly stops selection mode (it used to leave an empty selection). This change may also solve some weird similar issues in extracted mode where it is sometimes possible to end up with a 0-length selection. It may also impact Bug 5555929 since spellCheckSpans will now be correctly updated on ANY text change. 3. the before != after test is flawed. When this method is called, the text has been changed and selection mode should be stopped even when the new text happens to have the same size. Change-Id: I869ef728662f4350f22ed6149dd42db193c333ed --- core/java/android/widget/TextView.java | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index b106cc520ce0f..60c1ce96c06d3 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -7616,6 +7616,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener list.get(i).onTextChanged(text, start, before, after); } } + + updateSpellCheckSpans(start, start + after); + + // Hide the controllers as soon as text is modified (typing, procedural...) + // We do not hide the span controllers, since they can be added when a new text is + // inserted into the text view (voice IME). + hideCursorControllers(); } /** @@ -7655,15 +7662,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener sendOnTextChanged(buffer, start, before, after); onTextChanged(buffer, start, before, after); - - updateSpellCheckSpans(start, start + after); - - // Hide the controllers if the amount of content changed - if (before != after) { - // We do not hide the span controllers, as they can be added when a new text is - // inserted into the text view - hideCursorControllers(); - } } /** @@ -10840,7 +10838,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener // Handles can not cross and selection is at least one character final int selectionEnd = getSelectionEnd(); - if (offset >= selectionEnd) offset = selectionEnd - 1; + if (offset >= selectionEnd) offset = Math.max(0, selectionEnd - 1); positionAtCursorOffset(offset, false); } @@ -10882,7 +10880,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener // Handles can not cross and selection is at least one character final int selectionStart = getSelectionStart(); - if (offset <= selectionStart) offset = selectionStart + 1; + if (offset <= selectionStart) offset = Math.min(selectionStart + 1, mText.length()); positionAtCursorOffset(offset, false); }