Skip to content

Commit

Permalink
Handle Swift runtime failure: arithmetic overflow
Browse files Browse the repository at this point in the history
  • Loading branch information
azisramdhan committed Dec 22, 2024
1 parent c3c60fa commit 3d7829e
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 7 deletions.
14 changes: 14 additions & 0 deletions litewallet/Platform/Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -558,3 +558,17 @@ extension Dictionary where Key: ExpressibleByStringLiteral, Value: Any {
return jstring
}
}

extension UInt64 {
/// Performs a safe addition, returning `nil` if overflow occurs.
func safeAddition(_ value: UInt64) -> UInt64? {
let (result, overflow) = addingReportingOverflow(value)
return overflow ? nil : result
}

/// Performs a safe subtraction, returning `nil` if underflow occurs.
func safeSubtraction(_ value: UInt64) -> UInt64? {
let (result, underflow) = subtractingReportingOverflow(value)
return underflow ? nil : result
}
}
25 changes: 18 additions & 7 deletions litewallet/ViewModels/Transaction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,29 @@ class Transaction {
{
opsAmount = opsOutput.amount
}

self.fee = fee + opsAmount

// Safely calculate fee = fee + opsAmount
guard let safeFee = fee.safeAddition(opsAmount) else { return nil }
self.fee = safeFee

let amountReceived = wallet.amountReceivedFromTx(tx)
let amountSent = wallet.amountSentByTx(tx) - opsAmount

if amountSent > 0, (amountReceived + fee) == amountSent {
// Safely calculate amountSent = wallet.amountSentByTx(tx) - opsAmount
guard let safeAmountSent = wallet.amountSentByTx(tx).safeSubtraction(opsAmount) else { return nil }

// Safely calculate (amountReceived + fee)
guard let safeSum = amountReceived.safeAddition(fee) else { return nil }

if safeAmountSent > 0, safeAmountSent == safeSum {
direction = .moved
satoshis = amountSent
} else if amountSent > 0 {
satoshis = safeAmountSent
} else if safeAmountSent > 0 {
// Safely calculate (safeAmountSent - amountReceived - fee)
guard let safeSatoshis = safeAmountSent
.safeSubtraction(amountReceived)?
.safeSubtraction(fee) else { return nil }
direction = .sent
satoshis = amountSent - amountReceived - fee
satoshis = safeSatoshis
} else {
direction = .received
satoshis = amountReceived
Expand Down

0 comments on commit 3d7829e

Please sign in to comment.