qetxfinalizer: regex doesn't cover all, invalid Decimal -> 0 in TxFeeSlider.userFeeRate setter.
What changed, and why it matters
This commit fixes a crash in Electrum's mobile/QML fee slider. When a user typed a fee rate that the input regex allowed but Python's Decimal parser rejected, the app would crash with an 'InvalidOperation' exception instead of gracefully falling back to zero. The fix catches that exception and treats the bad value as 0, preventing the app from freezing or closing unexpectedly.
Apply the patch. Consider aligning the QML input validator regex with Decimal's accepted grammar, or sanitizing input before conversion, to reduce reliance on exception handling for normal user input.
Security signals we found
Unhandled exception in user-input parsing path
UI crash / denial-of-service via malformed fee-rate input
Input validation gap between regex and Decimal parser
Evidence from the diff
In electrum/gui/qml/qetxfinalizer.py, TxFeeSlider.userFeeRate setter converts the user-supplied string userFeerate to a Decimal. The original code did not catch decimal.InvalidOperation, so malformed numeric strings accepted by the QML regex (e.g., locale-specific formats, empty-ish strings, or strings with characters Decimal disallows) would raise an unhandled exception. The patch imports InvalidOperation and wraps the Decimal() call in a try/except that sets as_decimal = 0 on failure, then continues to build the FeePolicy. This is a robustness fix, not a cryptographic or network security issue.
Changed components
electrum/gui/qml/qetxfinalizer.pyTxFeeSlider.userFeeRate setterQML mobile GUI fee-rate inputInspect captured patch +5 / −2
diff --git a/electrum/gui/qml/qetxfinalizer.py b/electrum/gui/qml/qetxfinalizer.py
index d0457c8..e3d0da1 100644
--- a/electrum/gui/qml/qetxfinalizer.py
+++ b/electrum/gui/qml/qetxfinalizer.py
@@ -1,7 +1,7 @@
import copy
from enum import IntEnum
import threading
-from decimal import Decimal
+from decimal import Decimal, InvalidOperation
from typing import Optional, TYPE_CHECKING, Callable
from functools import partial
@@ -219,7 +219,10 @@ class TxFeeSlider(FeeSlider):
if self._userFeerate != userFeerate:
self._logger.warn('userFeerate')
self._userFeerate = userFeerate
- as_decimal = Decimal(userFeerate) if userFeerate else 0
+ try:
+ as_decimal = Decimal(userFeerate) if userFeerate else 0
+ except InvalidOperation:
+ as_decimal = 0
user_feerate = int(as_decimal * 1000)
self._fee_policy = FeePolicy(f'feerate:{user_feerate}')
self.userFeerateChanged.emit()
Why this scored 36/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.