Skip to content

fix(core): guard addresscodec against short/malformed payloads#342

Open
e-desouza wants to merge 2 commits into
mainfrom
fix/issue-280-addresscodec-panic
Open

fix(core): guard addresscodec against short/malformed payloads#342
e-desouza wants to merge 2 commits into
mainfrom
fix/issue-280-addresscodec-panic

Conversation

@e-desouza

Copy link
Copy Markdown
Collaborator

Why

decode_base58, _get_tag_from_buffer, and xaddress_to_classic_address all sliced byte arrays without length checks. A valid-checksum base58 string whose decoded payload was shorter than expected reached slice operations that panicked instead of returning an error.

Fixes #280.

What changed

  • decode_base58: added if decoded.len() < prefix_len guard returning UnexpectedPayloadLength { expected, found }.
  • _get_tag_from_buffer: added if buffer.len() < TAG_SUFFIX_MIN_LEN guard (9 bytes: 1 flag + 8 tag).
  • xaddress_to_classic_address: added if decoded.len() < XADDRESS_MIN_PAYLOAD_LEN guard (22 bytes: 2 prefix + 20 address) before any slicing.
  • Named constants XADDRESS_MIN_PAYLOAD_LEN = 22 and TAG_SUFFIX_MIN_LEN = 9 replace bare literals.
  • Updated guard comment to describe the exact slice operations each threshold protects.

How to validate

cargo test --release

New tests: test_decode_base58_short_payload_returns_error, test_xaddress_to_classic_too_short_returns_error, test_is_valid_xaddress_short_returns_false, test_get_tag_from_buffer_short_suffix_returns_error.

@codecov

codecov Bot commented Jul 12, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 86.73%. Comparing base (c83df4f) to head (9536126).

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #342      +/-   ##
==========================================
+ Coverage   86.71%   86.73%   +0.01%     
==========================================
  Files         252      252              
  Lines       32630    32682      +52     
==========================================
+ Hits        28296    28347      +51     
- Misses       4334     4335       +1     
Flag Coverage Δ
integration 71.32% <ø> (ø)
unit 87.35% <100.00%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/core/addresscodec/mod.rs 95.12% <100.00%> (+0.39%) ⬆️
src/core/addresscodec/utils.rs 91.83% <100.00%> (+2.09%) ⬆️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens the address codec against short/malformed decoded payloads that previously caused slice panics, converting those cases into structured UnexpectedPayloadLength errors (fixing #280 / remote DoS risk when handling untrusted inputs).

Changes:

  • Added decoded-length guards in decode_base58, _get_tag_from_buffer, and xaddress_to_classic_address to prevent out-of-bounds slicing.
  • Introduced named constants (XADDRESS_MIN_PAYLOAD_LEN, TAG_SUFFIX_MIN_LEN) to document and enforce minimum payload sizes.
  • Added regression tests covering short-payload cases and ensuring errors are returned instead of panics.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
src/core/addresscodec/utils.rs Adds a decoded-length guard to decode_base58 and a regression test for short payload handling.
src/core/addresscodec/mod.rs Adds minimum-length constants and guards for X-address decoding/tag extraction, plus regression tests for short/malformed inputs.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/core/addresscodec/utils.rs Outdated
// address). Passing a 22-byte prefix exceeds the decoded payload length, so the
// length guard must return Err rather than panicking at the slice operation.
let long_prefix = [0u8; 22];
assert!(decode_base58(ENCODED, &long_prefix).is_err());
Comment thread src/core/addresscodec/mod.rs Outdated
.with_alphabet(&XRPL_ALPHABET)
.with_check()
.into_string();
assert!(xaddress_to_classic_address(&short).is_err());
…hort-payload tests

Replace bare is_err() assertions with matches! checks that pin the specific
UnexpectedPayloadLength { expected, found } values, ensuring the length
guards in decode_base58 and xaddress_to_classic_address fire for the
intended reason rather than any incidental error path.
@e-desouza
e-desouza force-pushed the fix/issue-280-addresscodec-panic branch from 9536126 to c61c26e Compare July 15, 2026 16:42
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.

decode_base58 / _get_tag_from_buffer panic on short payloads

2 participants