[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-taler-android] 01/02: [wallet] Don't allow entering invalid amoun
From: |
gnunet |
Subject: |
[taler-taler-android] 01/02: [wallet] Don't allow entering invalid amounts |
Date: |
Tue, 03 Jan 2023 15:28:19 +0100 |
This is an automated email from the git hooks/post-receive script.
torsten-grote pushed a commit to branch master
in repository taler-android.
commit 9bb3505277b8132c3fd0be52d9bbbc6078723ff2
Author: Torsten Grote <t@grobox.de>
AuthorDate: Tue Jan 3 11:22:42 2023 -0300
[wallet] Don't allow entering invalid amounts
#0007350
---
taler-kotlin-android/build.gradle | 4 +-
.../src/main/java/net/taler/common/Amount.kt | 44 +++++++++++++++++-----
.../java/net/taler/wallet/ReceiveFundsFragment.kt | 4 +-
.../java/net/taler/wallet/SendFundsFragment.kt | 4 +-
4 files changed, 41 insertions(+), 15 deletions(-)
diff --git a/taler-kotlin-android/build.gradle
b/taler-kotlin-android/build.gradle
index efd305f..69b4f4d 100644
--- a/taler-kotlin-android/build.gradle
+++ b/taler-kotlin-android/build.gradle
@@ -21,6 +21,7 @@ plugins {
}
android {
+ namespace 'net.taler.common'
compileSdkVersion 32
buildToolsVersion "$build_tools_version"
@@ -49,9 +50,6 @@ android {
excludes += ['META-INF/*.kotlin_module']
}
}
-
- namespace 'net.taler.common'
-
}
dependencies {
diff --git a/taler-kotlin-android/src/main/java/net/taler/common/Amount.kt
b/taler-kotlin-android/src/main/java/net/taler/common/Amount.kt
index 4a6e4b3..750a1de 100644
--- a/taler-kotlin-android/src/main/java/net/taler/common/Amount.kt
+++ b/taler-kotlin-android/src/main/java/net/taler/common/Amount.kt
@@ -25,8 +25,11 @@ import kotlin.math.floor
import kotlin.math.pow
import kotlin.math.roundToInt
-public class AmountParserException(msg: String? = null, cause: Throwable? =
null) : Exception(msg, cause)
-public class AmountOverflowException(msg: String? = null, cause: Throwable? =
null) : Exception(msg, cause)
+public class AmountParserException(msg: String? = null, cause: Throwable? =
null) :
+ Exception(msg, cause)
+
+public class AmountOverflowException(msg: String? = null, cause: Throwable? =
null) :
+ Exception(msg, cause)
@Serializable(with = KotlinXAmountSerializer::class)
public data class Amount(
@@ -50,7 +53,7 @@ public data class Amount(
* of the base currency value. For example, a fraction
* of 50_000_000 would correspond to 50 cents.
*/
- val fraction: Int
+ val fraction: Int,
) : Comparable<Amount> {
public companion object {
@@ -63,8 +66,8 @@ public data class Amount(
public const val MAX_FRACTION: Int = 99_999_999
public fun fromDouble(currency: String, value: Double): Amount {
- val intPart = Math.floor(value).toLong()
- val fraPart = Math.floor((value - intPart) *
FRACTIONAL_BASE).toInt()
+ val intPart = floor(value).toLong()
+ val fraPart = floor((value - intPart) * FRACTIONAL_BASE).toInt()
return Amount(currency, intPart, fraPart)
}
@@ -87,14 +90,34 @@ public data class Amount(
val fractionStr = valueSplit[1]
if (fractionStr.length > MAX_FRACTION_LENGTH)
throw AmountParserException("Fraction $fractionStr too
long")
- val fraction = "0.$fractionStr".toDoubleOrNull()
- ?.times(FRACTIONAL_BASE)
- ?.roundToInt()
- checkFraction(fraction)
+ checkFraction(fractionStr.getFraction())
} else 0
return Amount(checkCurrency(currency), value, fraction)
}
+ public fun isValidAmountStr(str: String): Boolean {
+ val split = str.split(".")
+ try {
+ checkValue(split[0].toLongOrNull())
+ } catch (e: AmountParserException) {
+ return false
+ }
+ // also check fraction, if it exists
+ if (split.size > 1) {
+ val fractionStr = split[1]
+ if (fractionStr.length > MAX_FRACTION_LENGTH) return false
+ val fraction = fractionStr.getFraction() ?: return false
+ return fraction <= MAX_FRACTION
+ }
+ return true
+ }
+
+ private fun String.getFraction(): Int? {
+ return "0.$this".toDoubleOrNull()
+ ?.times(FRACTIONAL_BASE)
+ ?.roundToInt()
+ }
+
public fun min(currency: String): Amount = Amount(currency, 0, 1)
public fun max(currency: String): Amount = Amount(currency, MAX_VALUE,
MAX_FRACTION)
@@ -132,7 +155,8 @@ public data class Amount(
public operator fun plus(other: Amount): Amount {
check(currency == other.currency) { "Can only subtract from same
currency" }
- val resultValue = value + other.value + floor((fraction +
other.fraction).toDouble() / FRACTIONAL_BASE).toLong()
+ val resultValue =
+ value + other.value + floor((fraction + other.fraction).toDouble()
/ FRACTIONAL_BASE).toLong()
if (resultValue > MAX_VALUE)
throw AmountOverflowException()
val resultFraction = (fraction + other.fraction) % FRACTIONAL_BASE
diff --git a/wallet/src/main/java/net/taler/wallet/ReceiveFundsFragment.kt
b/wallet/src/main/java/net/taler/wallet/ReceiveFundsFragment.kt
index 647512c..8ae96ad 100644
--- a/wallet/src/main/java/net/taler/wallet/ReceiveFundsFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/ReceiveFundsFragment.kt
@@ -55,6 +55,7 @@ import androidx.fragment.app.activityViewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import net.taler.common.Amount
+import net.taler.common.Amount.Companion.isValidAmountStr
import net.taler.wallet.exchanges.ExchangeItem
class ReceiveFundsFragment : Fragment() {
@@ -136,7 +137,8 @@ private fun ReceiveFundsIntro(
keyboardOptions = KeyboardOptions.Default.copy(keyboardType =
Decimal),
onValueChange = { input ->
isError = false
- text = input.filter { it.isDigit() || it == '.' }
+ val filtered = input.filter { it.isDigit() || it == '.' }
+ if (filtered.endsWith('.') || isValidAmountStr(filtered))
text = filtered
},
isError = isError,
label = {
diff --git a/wallet/src/main/java/net/taler/wallet/SendFundsFragment.kt
b/wallet/src/main/java/net/taler/wallet/SendFundsFragment.kt
index 640fbf7..c5348a3 100644
--- a/wallet/src/main/java/net/taler/wallet/SendFundsFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/SendFundsFragment.kt
@@ -52,6 +52,7 @@ import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.navigation.fragment.findNavController
import net.taler.common.Amount
+import net.taler.common.Amount.Companion.isValidAmountStr
class SendFundsFragment : Fragment() {
private val model: MainViewModel by activityViewModels()
@@ -126,7 +127,8 @@ private fun SendFundsIntro(
onValueChange = { input ->
isError = false
insufficientBalance = false
- text = input.filter { it.isDigit() || it == '.' }
+ val filtered = input.filter { it.isDigit() || it == '.' }
+ if (filtered.endsWith('.') || isValidAmountStr(filtered))
text = filtered
},
isError = isError || insufficientBalance,
label = {
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.