Fix non-standard numeral entry.

This commit is contained in:
Alex Hart
2021-12-01 15:53:55 -04:00
committed by GitHub
parent b981ac4fe4
commit f9a2208832
5 changed files with 68 additions and 5 deletions

View File

@@ -21,6 +21,7 @@ import org.thoughtcrime.securesms.components.settings.PreferenceModel
import org.thoughtcrime.securesms.payments.FiatMoneyUtil
import org.thoughtcrime.securesms.util.MappingAdapter
import org.thoughtcrime.securesms.util.MappingViewHolder
import org.thoughtcrime.securesms.util.StringUtil
import org.thoughtcrime.securesms.util.ViewUtil
import java.lang.Integer.min
import java.text.DecimalFormatSymbols
@@ -197,7 +198,19 @@ data class Boost(
val separator = DecimalFormatSymbols.getInstance().decimalSeparator
val separatorCount = min(1, currency.defaultFractionDigits)
val symbol: String = currency.getSymbol(Locale.getDefault())
val pattern: Pattern = "[0-9]*([$separator]){0,$separatorCount}[0-9]{0,${currency.defaultFractionDigits}}".toPattern()
/**
* From Character.isDigit:
*
* * '\u0030' through '\u0039', ISO-LATIN-1 digits ('0' through '9')
* * '\u0660' through '\u0669', Arabic-Indic digits
* * '\u06F0' through '\u06F9', Extended Arabic-Indic digits
* * '\u0966' through '\u096F', Devanagari digits
* * '\uFF10' through '\uFF19', Fullwidth digits
*/
val digitsGroup: String = "[\\u0030-\\u0039]|[\\u0660-\\u0669]|[\\u06F0-\\u06F9]|[\\u0966-\\u096F]|[\\uFF10-\\uFF19]"
val pattern: Pattern = "($digitsGroup)*([$separator]){0,$separatorCount}($digitsGroup){0,${currency.defaultFractionDigits}}".toPattern()
val symbolPattern: Regex = """\s*${Regex.escape(symbol)}\s*""".toRegex()
val leadingZeroesPattern: Regex = """^0*""".toRegex()
@@ -211,7 +224,7 @@ data class Boost(
): CharSequence? {
val result = dest.subSequence(0, dstart).toString() + source.toString() + dest.subSequence(dend, dest.length)
val resultWithoutCurrencyPrefix = result.removePrefix(symbol).removeSuffix(symbol).trim()
val resultWithoutCurrencyPrefix = StringUtil.stripBidiIndicator(result.removePrefix(symbol).removeSuffix(symbol).trim())
if (resultWithoutCurrencyPrefix.length == 1 && !resultWithoutCurrencyPrefix.isDigitsOnly() && resultWithoutCurrencyPrefix != separator.toString()) {
return dest.subSequence(dstart, dend)
@@ -262,7 +275,14 @@ data class Boost(
}
val withoutSymbol = s.removePrefix(symbol).removeSuffix(symbol).trim().toString()
val withoutLeadingZeroes = withoutSymbol.replace(leadingZeroesPattern, "")
val withoutLeadingZeroes: String = try {
NumberFormat.getInstance().apply {
isGroupingUsed = false
}.format(withoutSymbol.toBigDecimal()) + (if (withoutSymbol.endsWith(separator)) separator else "")
} catch (e: NumberFormatException) {
withoutSymbol
}.replace(leadingZeroesPattern, "")
if (withoutSymbol != withoutLeadingZeroes) {
text?.removeTextChangedListener(this)

View File

@@ -21,6 +21,7 @@ import org.thoughtcrime.securesms.components.settings.app.subscription.DonationP
import org.thoughtcrime.securesms.keyvalue.SignalStore
import org.thoughtcrime.securesms.util.InternetConnectionObserver
import org.thoughtcrime.securesms.util.PlatformCurrencyUtil
import org.thoughtcrime.securesms.util.StringUtil
import org.thoughtcrime.securesms.util.livedata.Store
import java.lang.NumberFormatException
import java.math.BigDecimal
@@ -196,7 +197,8 @@ class BoostViewModel(
}
}
fun setCustomAmount(amount: String) {
fun setCustomAmount(rawAmount: String) {
val amount = StringUtil.stripBidiIndicator(rawAmount)
val bigDecimalAmount: BigDecimal = if (amount.isEmpty() || amount == DecimalFormatSymbols.getInstance().decimalSeparator.toString()) {
BigDecimal.ZERO
} else {

View File

@@ -233,6 +233,10 @@ public final class StringUtil {
return text.replaceAll("[\\u2068\\u2069\\u202c]", "");
}
public static @NonNull String stripBidiIndicator(@NonNull String text) {
return text.replace("\u200F", "");
}
/**
* Trims a {@link CharSequence} of starting and trailing whitespace. Behavior matches
* {@link String#trim()} to preserve expectations around results.