Skip to content

Commit e244868

Browse files
author
Gilles Debunne
committed
Final fix in SpannableStringBuilder.
Bug 6448052 The empty EXCLUSIVE removal condition was incorrect. Also changed the unit test the didn't catch this problem. Change-Id: I5576d830cdfa6cc3716c878fb698695a2978b296
1 parent 4380f95 commit e244868

File tree

1 file changed

+11
-8
lines changed

1 file changed

+11
-8
lines changed

core/java/android/text/SpannableStringBuilder.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,7 @@ private void change(int start, int end, CharSequence cs, int csStart, int csEnd)
308308
resizeFor(mText.length + nbNewChars - mGapLength);
309309
}
310310

311+
final boolean textIsRemoved = replacementLength == 0;
311312
// The removal pass needs to be done before the gap is updated in order to broadcast the
312313
// correct previous positions to the correct intersecting SpanWatchers
313314
if (replacedLength > 0) { // no need for span fixup on pure insertion
@@ -319,12 +320,15 @@ private void change(int start, int end, CharSequence cs, int csStart, int csEnd)
319320
while (i < mSpanCount) {
320321
if ((mSpanFlags[i] & Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) ==
321322
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE &&
322-
mSpanStarts[i] >= start && mSpanStarts[i] < mGapStart + mGapLength &&
323-
mSpanEnds[i] >= start && mSpanEnds[i] < mGapStart + mGapLength) {
323+
mSpanStarts[i] >= start && mSpanStarts[i] < mGapStart + mGapLength &&
324+
mSpanEnds[i] >= start && mSpanEnds[i] < mGapStart + mGapLength &&
325+
// This condition indicates that the span would become empty
326+
(textIsRemoved || mSpanStarts[i] > start || mSpanEnds[i] < mGapStart)) {
324327
removeSpan(i);
325-
} else {
326-
i++;
328+
continue; // do not increment i, spans will be shifted left in the array
327329
}
330+
331+
i++;
328332
}
329333
}
330334

@@ -338,7 +342,6 @@ private void change(int start, int end, CharSequence cs, int csStart, int csEnd)
338342

339343
if (replacedLength > 0) { // no need for span fixup on pure insertion
340344
final boolean atEnd = (mGapStart + mGapLength == mText.length);
341-
final boolean textIsRemoved = replacementLength == 0;
342345

343346
for (int i = 0; i < mSpanCount; i++) {
344347
final int startFlag = (mSpanFlags[i] & START_MASK) >> START_SHIFT;
@@ -390,9 +393,9 @@ private int updatedIntervalBound(int offset, int start, int nbNewChars, int flag
390393
return mGapStart + mGapLength;
391394
}
392395
} else { // MARK
393-
// MARKs should be moved to the start, with the exception of a mark located at the
394-
// end of the range (which will be < mGapStart + mGapLength since mGapLength > 0)
395-
// which should stay 'unchanged' at the end of the replaced text.
396+
// MARKs should be moved to the start, with the exception of a mark located at
397+
// the end of the range (which will be < mGapStart + mGapLength since mGapLength
398+
// is > 0, which should stay 'unchanged' at the end of the replaced text.
396399
if (textIsRemoved || offset < mGapStart - nbNewChars) {
397400
return start;
398401
} else {

0 commit comments

Comments
 (0)