taler-ios

iOS apps for GNU Taler (wallet)
Log | Files | Refs | README | LICENSE

commit d35cc0b39011f4efa1ae2668ef944ca3c6d0b494
parent 96cd8a7fab1aae86dd846a7b89d4ae5dda8cf2a6
Author: Marc Stibane <marc@taler.net>
Date:   Thu, 20 Aug 2026 19:27:16 +0200

AI: ASCII only

Diffstat:
Mtaler-swift/Sources/taler-swift/Amount.swift | 17++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/taler-swift/Sources/taler-swift/Amount.swift b/taler-swift/Sources/taler-swift/Amount.swift @@ -259,6 +259,14 @@ public final class Amount: Codable, Hashable, @unchecked Sendable, CustomStringC /// - Throws: /// - `AmountError.invalidStringRepresentation` if the string cannot be parsed. /// - `AmountError.invalidAmount` if the string can be parsed, but the resulting amount is not valid. + /// The protocol's amount syntax is ASCII-only. `UInt64.init(_: String)` accepts a + /// leading "+" and `Character.wholeNumberValue` is defined for every Unicode decimal + /// digit (e.g. Arabic-Indic), so both have to be screened out here - wallet-core's + /// Amounts.parse() and api-common.rst reject those spellings. + private static func isASCIIDigits(_ s: String) -> Bool { + !s.isEmpty && s.allSatisfy { $0.isASCII && $0.isNumber } + } + public init(fromString string: String) throws { if let separatorIndex = string.firstIndex(of: ":") { self.currency = String(string[..<separatorIndex]) @@ -272,17 +280,20 @@ public final class Amount: Codable, Hashable, @unchecked Sendable, CustomStringC if (fractionStr.count > Self.fractionalBaseDigits) { throw AmountError.invalidStringRepresentation } - guard let intValue = UInt64(integerStr) else { throw AmountError.invalidStringRepresentation } + guard Self.isASCIIDigits(integerStr), + let intValue = UInt64(integerStr) else { throw AmountError.invalidStringRepresentation } self.integer = intValue self.fraction = 0 var digitValue = fractionalBase() / 10 for char in fractionStr { - guard let digit = char.wholeNumberValue else { throw AmountError.invalidStringRepresentation } + guard char.isASCII, + let digit = char.wholeNumberValue else { throw AmountError.invalidStringRepresentation } self.fraction += digitValue * UInt32(digit) digitValue /= 10 } } else { - guard let intValue = UInt64(amountStr) else { throw AmountError.invalidStringRepresentation } + guard Self.isASCIIDigits(amountStr), + let intValue = UInt64(amountStr) else { throw AmountError.invalidStringRepresentation } self.integer = intValue self.fraction = 0 }