Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bee1df88 authored by Raph Levien's avatar Raph Levien
Browse files

Finer grained character boundaries in computing SMS fragment lengths

The standard Java character iterator has potentially unbounded
distance between character boundaries, meaning that when breaking an
SMS message into fragments it's not safe to assume that the fragment
will contain such a boundary. This patch special-cases flags (pairs of
Regional Indicator Symbols) and also guarantees some progress in the
case of no boundary found.

Bug: 26210851
Change-Id: Ic16637a834af0dfe40197fbcdb3471c1bf5cd6d2
parent 468dcf57
Loading
Loading
Loading
Loading
+16 −1
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@ import java.util.Arrays;

import android.provider.Telephony;
import android.telephony.SmsMessage;
import android.text.Emoji;

/**
 * Base class declaring the specific methods and members for SmsMessage.
@@ -367,7 +368,21 @@ public abstract class SmsMessageBase {
            BreakIterator breakIterator = BreakIterator.getCharacterInstance();
            breakIterator.setText(msgBody.toString());
            if (!breakIterator.isBoundary(nextPos)) {
                nextPos = breakIterator.preceding(nextPos);
                int breakPos = breakIterator.preceding(nextPos);
                while (breakPos + 4 <= nextPos
                        && Emoji.isRegionalIndicatorSymbol(
                            Character.codePointAt(msgBody, breakPos))
                        && Emoji.isRegionalIndicatorSymbol(
                            Character.codePointAt(msgBody, breakPos + 2))) {
                    // skip forward over flags (pairs of Regional Indicator Symbol)
                    breakPos += 4;
                }
                if (breakPos > currentPosition) {
                    nextPos = breakPos;
                } else if (Character.isHighSurrogate(msgBody.charAt(nextPos - 1))) {
                    // no character boundary in this fragment, try to at least land on a code point
                    nextPos -= 1;
                }
            }
        }
        return nextPos;