Skip to content

Fix SkipWhitespace returning early EOF on whitespace-only chunks#2461

Open
gabrielrondon wants to merge 1 commit intostellar:mainfrom
gabrielrondon:fix/skip-whitespace-eof
Open

Fix SkipWhitespace returning early EOF on whitespace-only chunks#2461
gabrielrondon wants to merge 1 commit intostellar:mainfrom
gabrielrondon:fix/skip-whitespace-eof

Conversation

@gabrielrondon
Copy link

What

Fix SkipWhitespace::read() signaling EOF when a read chunk contains only whitespace bytes. Add unit tests for the reader.

Why

When base64 XDR input contains whitespace (e.g., newlines from terminal paste or multiline file), read() returns Ok(0) for whitespace-only chunks. The Read trait interprets Ok(0) as EOF, causing silent truncation and subsequent XDR decode errors.

The fix loops until at least one non-whitespace byte is found or the inner reader returns true EOF.

Affects all commands using tx_envelope_from_input(): tx hash, tx sign, tx send, tx simulate, tx op add.

Known limitations

The upstream stellar-xdr crate has the same bug in its own SkipWhitespace (used by tx decode). This PR only fixes the stellar-cli copy. The upstream fix should be tracked separately in stellar/rs-stellar-xdr.

Closes #2431

When a read() call returns a buffer containing only whitespace bytes,
SkipWhitespace returns Ok(0) which the Read trait interprets as EOF.
This causes silent truncation of base64 input containing whitespace
(e.g., newlines from terminal paste or file formatting).

Fix by looping until at least one non-whitespace byte is found or the
inner reader returns true EOF.

Closes stellar#2431
Copilot AI review requested due to automatic review settings March 23, 2026 23:36
@github-project-automation github-project-automation bot moved this to Backlog (Not Ready) in DevX Mar 23, 2026
Copy link
Contributor

Copilot AI left a comment

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 fixes SkipWhitespace::read() in the tx XDR input path so it won’t incorrectly signal EOF (Ok(0)) when a read chunk contains only whitespace, preventing silent truncation of base64-encoded XDR read from stdin/args.

Changes:

  • Update SkipWhitespace<R>::read() to keep reading until it produces at least one non-whitespace byte or the inner reader reaches true EOF.
  • Add unit tests for SkipWhitespace behavior.

Comment on lines +83 to +99
#[test]
fn skip_whitespace_preserves_content() {
let input = Cursor::new(b"helloworld");
let mut reader = SkipWhitespace::new(input);
let mut result = String::new();
reader.read_to_string(&mut result).unwrap();
assert_eq!(result, "helloworld");
}

#[test]
fn skip_whitespace_strips_all_whitespace_types() {
let input = Cursor::new(b"hello \t\n\r world");
let mut reader = SkipWhitespace::new(input);
let mut result = String::new();
reader.read_to_string(&mut result).unwrap();
assert_eq!(result, "helloworld");
}
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

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

The new unit tests don’t exercise the bug fixed by the loop: the failure only happens when the inner reader returns a chunk that contains only whitespace but more non-whitespace bytes arrive in a later read. Cursor typically reads the whole buffer in one call, so these tests would also pass with the previous (buggy) implementation. Consider adding a test with a chunked/step reader (e.g., returns b"AAAA", then b"\n\n", then b"BBBB") to ensure SkipWhitespace::read() does not signal EOF early, and/or an integration test in soroban-test that pipes multi-line base64 into stellar tx hash/tx sign/tx send.

Copilot generated this review using guidance from repository custom instructions.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Backlog (Not Ready)

Development

Successfully merging this pull request may close these issues.

xdr decode commands fails with XDR decode error when base64 input contains whitespace

2 participants