Skip to content

fix(cli): keep whitespace inside a JSON transaction read via @file - #461

Open
shahan-khatchadourian-anchorage wants to merge 1 commit into
mainfrom
cli/json-input-preserves-whitespace
Open

fix(cli): keep whitespace inside a JSON transaction read via @file#461
shahan-khatchadourian-anchorage wants to merge 1 commit into
mainfrom
cli/json-input-preserves-whitespace

Conversation

@shahan-khatchadourian-anchorage

Copy link
Copy Markdown
Contributor

@file and @- strip every ASCII-whitespace byte from the buffer. That rule is correct for hex and base64, which cannot legitimately contain whitespace, and it lets a user paste line-wrapped hex from a block explorer without cleanup. It is wrong for a JSON transaction envelope, whose string values can legitimately contain spaces:

-t '{"memo":"AAA BBB  CCC"}'      -> memo is "AAA BBB  CCC"
@file with the same bytes         -> memo is "AAABBBCCC"

Two input methods for one transaction have to decode the same bytes.

The rule

Internal stripping is confined to buffers that are not JSON, detected by a leading { after trimming. Leading and trailing whitespace still comes off either way, so a file ending in a newline behaves like the same value passed inline.

A leading { is a complete test for the formats this CLI accepts: every JSON transaction format is a top-level object (I checked — none is an array), and neither the hex nor the base64 alphabet contains {, so the two cases cannot be confused. The doc comment states that invariant so it can be rechecked when a format is added.

Worth knowing

A \n escape in a JSON file is two characters, neither of them ASCII whitespace, so it survived the strip already. The rule removed legitimate spaces while preserving the sequence that actually matters for field spoofing. Sanitizing that sequence belongs at the field insertion site and is unaffected here.

No chain on main accepts JSON input yet — that arrives with the NEAR intents envelope — so this fixes the bug before it becomes reachable. The parity is already demonstrable: passing the same JSON both ways now produces byte-identical results, where previously the @file path saw different bytes.

Testing

Three tests, each verified to fail without the fix and pass with it. The four pre-existing hex tests pass under both, confirming the line-wrapped-hex behavior is untouched.

🤖 Generated with Claude Code

`@file` and `@-` strip every ASCII-whitespace byte from the buffer. That
rule is correct for hex and base64, which cannot legitimately contain
whitespace, and it lets a user paste line-wrapped hex from a block
explorer without cleanup. It is wrong for a JSON transaction envelope,
whose string values can legitimately contain spaces:

    -t '{"memo":"AAA BBB  CCC"}'        -> memo is "AAA BBB  CCC"
    @file containing the same bytes     -> memo is "AAABBBCCC"

Two input methods for one transaction have to decode the same bytes.

Confine the internal-whitespace strip to buffers that are not JSON,
detected by a leading `{` after trimming. Every JSON transaction format
this CLI accepts is an object and no hex or base64 body can begin with
that byte, so the two cases cannot be confused. Leading and trailing
whitespace still comes off either way, so a file ending in a newline
behaves like the same value passed inline.

A `\n` escape in a JSON file is two characters, neither of them ASCII
whitespace, so it survived the strip already -- the rule removed
legitimate spaces while preserving the sequence that matters for field
spoofing. Sanitization of that sequence belongs at the field insertion
site and is unaffected by this change.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 CLI transaction input normalization so @file / @- no longer strip meaningful whitespace from JSON transaction envelopes, while preserving the existing whitespace-stripping behavior for hex/base64 inputs.

Changes:

  • Adds JSON-aware buffer resolution: detect JSON by leading { (after trimming start) and avoid internal whitespace stripping for JSON.
  • Keeps internal ASCII-whitespace stripping for hex/base64 buffers read via @file / @-.
  • Adds unit tests covering JSON whitespace preservation and ensuring hex stripping behavior remains unchanged.

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

Comment on lines +60 to +64
if raw.trim_start().starts_with('{') {
raw.trim().to_string()
} else {
strip_ascii_whitespace(raw)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants