diff options
author | Raph Levien <raph@google.com> | 2016-02-17 15:04:17 -0800 |
---|---|---|
committer | Raph Levien <raph@google.com> | 2016-02-19 10:05:07 -0800 |
commit | 9d26bbe1ee14fcab80e2a4faa1f473df3906351c (patch) | |
tree | e2293615f22ce68fad223f52e9d166d0c14271c4 | |
parent | db789b1a999f8f10135405caebd7962029a78ba1 (diff) | |
download | base-9d26bbe1ee14fcab80e2a4faa1f473df3906351c.tar.gz |
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
-rw-r--r-- | src/java/com/android/internal/telephony/SmsMessageBase.java | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/src/java/com/android/internal/telephony/SmsMessageBase.java b/src/java/com/android/internal/telephony/SmsMessageBase.java index 1d50834d3e0f..3338772796a3 100644 --- a/src/java/com/android/internal/telephony/SmsMessageBase.java +++ b/src/java/com/android/internal/telephony/SmsMessageBase.java @@ -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; |