From 015ad4247d5616f7cf7d05456a40a2a625faf383 Mon Sep 17 00:00:00 2001 From: Jun Luo <4catcode@gmail.com> Date: Sun, 1 Feb 2026 09:34:29 +0800 Subject: [PATCH] fix: use `StandardCharsets.UTF_8` for byte array to string conversions --- CHANGELOG.md | 1 + src/main/java/org/stellar/sdk/Sep10Challenge.java | 5 ++++- src/main/java/org/stellar/sdk/Sep45Challenge.java | 15 ++++++++------- src/main/java/org/stellar/sdk/Util.java | 3 ++- .../sdk/operations/AllowTrustOperation.java | 9 +++++++-- 5 files changed, 22 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 28ca6b762..15b6c0871 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - fix: replace assert statements with explicit null checks in `Federation` class to ensure validation is not bypassed when assertions are disabled. - fix: add overflow check in `TimeBounds.expiresAfter()` to prevent integer overflow when timeout is too large. - fix: add validation for `ManageDataOperation` value length to ensure it does not exceed 64 bytes. +- fix: use `StandardCharsets.UTF_8` explicitly when converting byte arrays to strings to ensure consistent behavior across different platforms. ## 2.2.1 diff --git a/src/main/java/org/stellar/sdk/Sep10Challenge.java b/src/main/java/org/stellar/sdk/Sep10Challenge.java index adbcd5797..bcb460446 100644 --- a/src/main/java/org/stellar/sdk/Sep10Challenge.java +++ b/src/main/java/org/stellar/sdk/Sep10Challenge.java @@ -1,6 +1,7 @@ package org.stellar.sdk; import java.math.BigInteger; +import java.nio.charset.StandardCharsets; import java.security.SecureRandom; import java.util.ArrayList; import java.util.Arrays; @@ -316,7 +317,9 @@ public static ChallengeTransaction readChallengeTransaction( byte[] nonce; try { - nonce = Base64Factory.getInstance().decode(new String(manageDataOperation.getValue())); + nonce = + Base64Factory.getInstance() + .decode(new String(manageDataOperation.getValue(), StandardCharsets.UTF_8)); } catch (IllegalArgumentException e) { throw new InvalidSep10ChallengeException( "Failed to decode random nonce provided in ManageData operation.", e); diff --git a/src/main/java/org/stellar/sdk/Sep45Challenge.java b/src/main/java/org/stellar/sdk/Sep45Challenge.java index 30437e5ba..5cf9aa846 100644 --- a/src/main/java/org/stellar/sdk/Sep45Challenge.java +++ b/src/main/java/org/stellar/sdk/Sep45Challenge.java @@ -1,6 +1,7 @@ package org.stellar.sdk; import java.io.IOException; +import java.nio.charset.StandardCharsets; import java.security.SecureRandom; import java.util.ArrayList; import java.util.Arrays; @@ -371,25 +372,25 @@ public static ChallengeAuthorizationEntries readChallengeAuthorizationEntries( switch (key) { case "account": - account = new String(Scv.fromString(valueVal)); + account = new String(Scv.fromString(valueVal), StandardCharsets.UTF_8); break; case "home_domain": - homeDomain = new String(Scv.fromString(valueVal)); + homeDomain = new String(Scv.fromString(valueVal), StandardCharsets.UTF_8); break; case "nonce": - nonce = new String(Scv.fromString(valueVal)); + nonce = new String(Scv.fromString(valueVal), StandardCharsets.UTF_8); break; case "web_auth_domain": - webAuthDomainValue = new String(Scv.fromString(valueVal)); + webAuthDomainValue = new String(Scv.fromString(valueVal), StandardCharsets.UTF_8); break; case "web_auth_domain_account": - webAuthDomainAccount = new String(Scv.fromString(valueVal)); + webAuthDomainAccount = new String(Scv.fromString(valueVal), StandardCharsets.UTF_8); break; case "client_domain": - clientDomain = new String(Scv.fromString(valueVal)); + clientDomain = new String(Scv.fromString(valueVal), StandardCharsets.UTF_8); break; case "client_domain_account": - clientDomainAccount = new String(Scv.fromString(valueVal)); + clientDomainAccount = new String(Scv.fromString(valueVal), StandardCharsets.UTF_8); break; default: // Unknown argument, ignore diff --git a/src/main/java/org/stellar/sdk/Util.java b/src/main/java/org/stellar/sdk/Util.java index 37ea972cc..1ba3f941b 100644 --- a/src/main/java/org/stellar/sdk/Util.java +++ b/src/main/java/org/stellar/sdk/Util.java @@ -2,6 +2,7 @@ import java.io.IOException; import java.math.BigInteger; +import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; @@ -95,7 +96,7 @@ public static byte[] paddedByteArray(String string, int length) { * @return trimmed byte array */ static String paddedByteArrayToString(byte[] bytes) { - String[] strArray = new String(bytes).split("\0"); + String[] strArray = new String(bytes, StandardCharsets.UTF_8).split("\0"); if (strArray.length > 0) { return strArray[0]; } diff --git a/src/main/java/org/stellar/sdk/operations/AllowTrustOperation.java b/src/main/java/org/stellar/sdk/operations/AllowTrustOperation.java index df745213e..ab56e2284 100644 --- a/src/main/java/org/stellar/sdk/operations/AllowTrustOperation.java +++ b/src/main/java/org/stellar/sdk/operations/AllowTrustOperation.java @@ -1,5 +1,6 @@ package org.stellar.sdk.operations; +import java.nio.charset.StandardCharsets; import lombok.AllArgsConstructor; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -57,10 +58,14 @@ public static AllowTrustOperation fromXdr(AllowTrustOp op) { String assetCode; switch (op.getAsset().getDiscriminant()) { case ASSET_TYPE_CREDIT_ALPHANUM4: - assetCode = new String(op.getAsset().getAssetCode4().getAssetCode4()).trim(); + assetCode = + new String(op.getAsset().getAssetCode4().getAssetCode4(), StandardCharsets.UTF_8) + .trim(); break; case ASSET_TYPE_CREDIT_ALPHANUM12: - assetCode = new String(op.getAsset().getAssetCode12().getAssetCode12()).trim(); + assetCode = + new String(op.getAsset().getAssetCode12().getAssetCode12(), StandardCharsets.UTF_8) + .trim(); break; default: throw new IllegalArgumentException("Unknown asset code");