Skip to content

fix(http): preserve U+FFFF in JsonFormat string output - #7086

Merged
lvs0075 merged 1 commit into
tronprotocol:release_v4.8.3from
waynercheung:fix/jsonformat-uffff-escape
Nov 6, 2026
Merged

lvs0075 merged 1 commit into
tronprotocol:release_v4.8.3from
waynercheung:fix/jsonformat-uffff-escape

Conversation

@waynercheung

Copy link
Copy Markdown
Collaborator

What does this PR do?

  • Iterate JsonFormat.escapeText by index instead of CharacterIterator, so string fields containing U+FFFF are printed in full.
  • Encode valid surrogate pairs as \uXXXX\uXXXX, and replace unpaired surrogates with ?, the same character used when such a string is encoded to UTF-8.
  • Remove escapeNameStringText; name-string bytes fields call escapeText directly with identical output.

Why are these changes required?

CharacterIterator.DONE equals U+FFFF, so escapeText stopped at the first U+FFFF and the rest of the value was dropped from the HTTP JSON output. raw_data_hex and txID are computed from the full bytes, so a transaction rebuilt from that JSON by /wallet/broadcasttransaction has a different txID and fails signature validation. Affected fields include SmartContract.name, ABI entry/param name and type, Permission.permission_name, AssetIssueContract.id and Witness.url.

This PR has been tested by:

  • Unit Tests
    • JsonFormatEscapeTest: U+FFFF/U+FFFE at different positions, surrogate pairs and unpaired surrogates, and print -> packTransaction round trips for CreateSmartContract, AccountPermissionUpdateContract and AssetIssueContract with visible true and false, asserting identical raw_data bytes and txID.

Follow up

None.

Extra details

Behavior changes (release note)

  • HTTP and JSON-RPC buildTransaction responses now return the full value of string fields containing U+FFFF instead of a truncated one. During a rolling upgrade, nodes that are not yet upgraded still return the truncated value.
  • An unpaired surrogate in an in-memory string value is now printed as ? instead of raising an error.
  • Inbound parsing, stored bytes, txID and consensus are unchanged.

escapeText stopped at CharacterIterator.DONE, which equals U+FFFF, so
string fields containing it were truncated in HTTP JSON while txID
still covered the full bytes, causing SIGERROR on broadcast.

Iterate by index, replace unpaired surrogates with '?' to match the
encoded bytes, and drop the escapeNameStringText workaround.
@lvs0075
lvs0075 merged commit 4c1e24d into tronprotocol:release_v4.8.3 Nov 6, 2026
11 checks passed
@github-project-automation github-project-automation Bot moved this to Done in java-tron Nov 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants