refactor: narrow parse_address fallbacks to EmbitError in wallet.py
What changed, and why it matters
This change fixes a bug where pressing a device's cancel/back button during address parsing could be ignored or misreported as an 'invalid address' instead of letting the user exit. The code previously caught every possible error (including user interrupts) and treated them all as address validation failures. Now it only catches actual address-format errors from the embit library, allowing legitimate user interrupts to propagate normally.
Review other bare `except:` handlers in the codebase for similar swallowing of KeyboardInterrupt or SystemExit. Ensure parse_address callers handle KeyboardInterrupt appropriately. No immediate patch deployment is critical, but the fix should be included in the next release.
Security signals we found
Bare exception handler narrowed to specific library exception
User-triggered interrupt (KeyboardInterrupt) no longer swallowed
Regression test added for interrupt propagation in both code branches
Potential denial-of-service / user-control issue: cancellation could be ignored
Evidence from the diff
In src/krux/wallet.py, parse_address() previously used bare except: clauses around calls to embit.script.address_to_scriptpubkey(). This swallowed all exceptions, including KeyboardInterrupt, which on embedded/MicroPython devices is typically raised by user cancellation actions. The refactor imports EmbitError and narrows the exception handlers to except EmbitError:, so KeyboardInterrupt and other non-address errors propagate instead of being silently swallowed or re-raised as ValueError(‘invalid address’). A regression test verifies both uppercase and mixed-case address branches propagate KeyboardInterrupt.
Changed components
src/krux/wallet.py:parse_address()embit.script.address_to_scriptpubkey error handlingtests/test_wallet.pyInspect captured patch +24 / −3
diff --git a/src/krux/wallet.py b/src/krux/wallet.py
index 33e7925..a3c763f 100644
--- a/src/krux/wallet.py
+++ b/src/krux/wallet.py
@@ -482,7 +482,7 @@ def parse_address(address_data):
If the address cannot be derived, an exception is raised.
"""
- from embit.script import Script, address_to_scriptpubkey
+ from embit.script import Script, address_to_scriptpubkey, EmbitError
addr = address_data
sc = None
@@ -498,13 +498,13 @@ def parse_address(address_data):
sc = address_to_scriptpubkey(addr.lower())
if isinstance(sc, Script):
return addr.lower()
- except:
+ except EmbitError:
pass
if not isinstance(sc, Script):
try:
address_to_scriptpubkey(addr)
- except:
+ except EmbitError:
raise ValueError("invalid address")
return addr
diff --git a/tests/test_wallet.py b/tests/test_wallet.py
index 19a445d..816b5e3 100644
--- a/tests/test_wallet.py
+++ b/tests/test_wallet.py
@@ -1772,6 +1772,27 @@ def test_parse_address_raises_errors(mocker, m5stickv, tdata):
parse_address(case)
+def test_parse_address_propagates_keyboardinterrupt(mocker, m5stickv):
+ """KeyboardInterrupt must propagate, never be swallowed (line 501) or
+ relabeled 'invalid address' (line 507).
+
+ parse_address imports address_to_scriptpubkey *inside* the function, so the
+ patch target is embit.script.address_to_scriptpubkey — there is no
+ krux.wallet.address_to_scriptpubkey to patch.
+ """
+ from krux.wallet import parse_address
+
+ mocker.patch("embit.script.address_to_scriptpubkey", side_effect=KeyboardInterrupt)
+
+ # Uppercase input exercises the bech32-uppercase branch (line 501)
+ with pytest.raises(KeyboardInterrupt):
+ parse_address("BC1QX2ZUDAY8D6J4UFH4DF6E9TTD06LNFMN2CUZ0VN")
+
+ # Mixed-case input skips that branch and exercises the final attempt (line 507)
+ with pytest.raises(KeyboardInterrupt):
+ parse_address("bc1qx2zuday8d6j4ufh4df6e9ttd06lnfmn2cuz0vn")
+
+
def test_to_unambiguous_descriptor(mocker, m5stickv, tdata):
from embit.descriptor import Descriptor
from krux.wallet import to_unambiguous_descriptor
Why this scored 34/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.