Skip to content

fix: return InvalidData instead of panicking on crafted wallet bytes - #2751

Merged
zancas merged 1 commit into
bb/add-wallet-file-validation-thr_dfg7v7d7jvfrom
validate_returns_err_not_panic
Aug 29, 2026
Merged

fix: return InvalidData instead of panicking on crafted wallet bytes#2751
zancas merged 1 commit into
bb/add-wallet-file-validation-thr_dfg7v7d7jvfrom
validate_returns_err_not_panic

Conversation

@zancas

@zancas zancas commented Aug 28, 2026

Copy link
Copy Markdown
Member

This PR stacks on #2749 and repairs one review finding. LightWallet::validate documents an io::Result whose error names the byte offset reached. The read path it wraps carried seven expect() calls that panic on crafted-but-reachable inputs. A validation entry point must not abort on the malformed files it exists to reject.

The seven sites now return InvalidData errors. They are: a pre-32 birthday above u32::MAX; account ids with the hardened bit set in the unified key store, the unified address map, and the transparent address map; a hardened transparent address index; a version 35 file whose key store vector holds no account 0; and a stored min_confirmations of zero. The three identical account id reads collapse into one read_account_id helper.

Five regression tests craft minimal wallet prefixes that reach the five shallow sites. Each test asserts that validate returns an error instead of panicking. The birthday and min_confirmations sites sit behind fields whose grammars are impractical to hand-craft. Those two sites receive the same mechanical repair without dedicated fixtures. The expect() at the account 0 lookup in read_v0 stays, because the map is built one line above it and the lookup cannot fail.

🤖 Generated with Claude Code

LightWallet::validate promises an io::Result whose error names the byte
offset reached, but the read path it wraps carried seven expect() calls
that panic on crafted-but-reachable inputs: a pre-32 birthday above
u32::MAX, account ids with the hardened bit set in the unified key
store and in both address maps, a hardened transparent address index, a
version 35 file whose key store vector holds no account 0, and a stored
min_confirmations of zero. Each site now returns an InvalidData error
instead, and the three identical account id reads collapse into one
read_account_id helper.

Five regression tests craft minimal wallet prefixes that reach the five
shallow sites and assert validate returns an error rather than
aborting. The birthday and min_confirmations sites sit behind fields
whose grammars are impractical to hand-craft, so they are fixed by the
same mechanical transformation without dedicated fixtures.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@zancas
zancas merged commit d3989a2 into bb/add-wallet-file-validation-thr_dfg7v7d7jv Aug 29, 2026
20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant