From 0002d6bae69feb4a5195418ae99d520653c5e7dc Mon Sep 17 00:00:00 2001 From: Craig Raw Date: Mon, 13 Feb 2023 16:35:40 +0200 Subject: [PATCH] support detection of utf8 string script chunks --- .../java/com/sparrowwallet/drongo/Utils.java | 11 ++++++++ .../drongo/protocol/ScriptChunk.java | 25 +++++++++++++++++-- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/sparrowwallet/drongo/Utils.java b/src/main/java/com/sparrowwallet/drongo/Utils.java index 51c2f6a..4d7136f 100644 --- a/src/main/java/com/sparrowwallet/drongo/Utils.java +++ b/src/main/java/com/sparrowwallet/drongo/Utils.java @@ -13,6 +13,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.math.BigInteger; import java.nio.ByteBuffer; +import java.nio.charset.CharsetDecoder; import java.nio.charset.StandardCharsets; import java.util.*; @@ -31,6 +32,16 @@ public class Utils { return s.matches(BASE64_REGEX); } + public static boolean isUtf8(byte[] bytes) { + try { + CharsetDecoder decoder = StandardCharsets.UTF_8.newDecoder(); + decoder.decode(java.nio.ByteBuffer.wrap(bytes)); + return true; + } catch(Exception e) { + return false; + } + } + public static String bytesToHex(byte[] bytes) { char[] hexChars = new char[bytes.length * 2]; for ( int j = 0; j < bytes.length; j++ ) { diff --git a/src/main/java/com/sparrowwallet/drongo/protocol/ScriptChunk.java b/src/main/java/com/sparrowwallet/drongo/protocol/ScriptChunk.java index f74b4d4..ce559a1 100644 --- a/src/main/java/com/sparrowwallet/drongo/protocol/ScriptChunk.java +++ b/src/main/java/com/sparrowwallet/drongo/protocol/ScriptChunk.java @@ -7,6 +7,8 @@ import org.bouncycastle.util.encoders.Hex; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Objects; @@ -28,7 +30,11 @@ public class ScriptChunk { } public static ScriptChunk fromOpcode(int opcode) { - return new ScriptChunk(opcode, null); + return new ScriptChunk(opcode, opcode == ScriptOpCodes.OP_0 ? new byte[0] : null); + } + + public static ScriptChunk fromString(String strData, Charset charset) { + return fromData(strData.getBytes(charset)); } public static ScriptChunk fromData(byte[] data) { @@ -68,7 +74,7 @@ public class ScriptChunk { } public void write(OutputStream stream) throws IOException { - if (isOpCode()) { + if (isOpCode() && opcode != ScriptOpCodes.OP_0) { if(data != null) throw new IllegalStateException("Data must be null for opcode chunk"); stream.write(opcode); } else if (data != null) { @@ -126,6 +132,18 @@ public class ScriptChunk { } } + public boolean isString() { + if(data == null || data.length == 0) { + return false; + } + + if(isSignature() || isPubKey()) { + return false; + } + + return Utils.isUtf8(data); + } + public boolean isScript() { if(data == null || data.length == 0) { return false; @@ -213,6 +231,9 @@ public class ScriptChunk { if (data.length == 0) { return "OP_0"; } + if(Utils.isUtf8(data)) { + return new String(data, StandardCharsets.UTF_8); + } return Hex.toHexString(data); }