diff --git a/src/main/java/org/qortal/transform/transaction/ArbitraryTransactionTransformer.java b/src/main/java/org/qortal/transform/transaction/ArbitraryTransactionTransformer.java index e1514b4b..c3190f03 100644 --- a/src/main/java/org/qortal/transform/transaction/ArbitraryTransactionTransformer.java +++ b/src/main/java/org/qortal/transform/transaction/ArbitraryTransactionTransformer.java @@ -106,9 +106,9 @@ public class ArbitraryTransactionTransformer extends TransactionTransformer { if (version >= 5) { nonce = byteBuffer.getInt(); - name = Serialization.deserializeSizedString(byteBuffer, Name.MAX_NAME_SIZE); + name = Serialization.deserializeSizedStringV2(byteBuffer, Name.MAX_NAME_SIZE); - identifier = Serialization.deserializeSizedString(byteBuffer, ArbitraryTransaction.MAX_IDENTIFIER_LENGTH); + identifier = Serialization.deserializeSizedStringV2(byteBuffer, ArbitraryTransaction.MAX_IDENTIFIER_LENGTH); method = ArbitraryTransactionData.Method.valueOf(byteBuffer.getInt()); @@ -203,9 +203,9 @@ public class ArbitraryTransactionTransformer extends TransactionTransformer { if (arbitraryTransactionData.getVersion() >= 5) { bytes.write(Ints.toByteArray(arbitraryTransactionData.getNonce())); - Serialization.serializeSizedString(bytes, arbitraryTransactionData.getName()); + Serialization.serializeSizedStringV2(bytes, arbitraryTransactionData.getName()); - Serialization.serializeSizedString(bytes, arbitraryTransactionData.getIdentifier()); + Serialization.serializeSizedStringV2(bytes, arbitraryTransactionData.getIdentifier()); bytes.write(Ints.toByteArray(arbitraryTransactionData.getMethod().value)); @@ -274,9 +274,9 @@ public class ArbitraryTransactionTransformer extends TransactionTransformer { if (arbitraryTransactionData.getVersion() >= 5) { bytes.write(Ints.toByteArray(arbitraryTransactionData.getNonce())); - Serialization.serializeSizedString(bytes, arbitraryTransactionData.getName()); + Serialization.serializeSizedStringV2(bytes, arbitraryTransactionData.getName()); - Serialization.serializeSizedString(bytes, arbitraryTransactionData.getIdentifier()); + Serialization.serializeSizedStringV2(bytes, arbitraryTransactionData.getIdentifier()); bytes.write(Ints.toByteArray(arbitraryTransactionData.getMethod().value)); diff --git a/src/main/java/org/qortal/utils/Serialization.java b/src/main/java/org/qortal/utils/Serialization.java index 8c3c43ed..26888477 100644 --- a/src/main/java/org/qortal/utils/Serialization.java +++ b/src/main/java/org/qortal/utils/Serialization.java @@ -100,7 +100,50 @@ public class Serialization { return bytes; } + /** + * Original serializeSizedString() method used in various transaction types + * @param bytes + * @param string + * @throws UnsupportedEncodingException + * @throws IOException + */ public static void serializeSizedString(ByteArrayOutputStream bytes, String string) throws UnsupportedEncodingException, IOException { + byte[] stringBytes = string.getBytes(StandardCharsets.UTF_8); + bytes.write(Ints.toByteArray(stringBytes.length)); + bytes.write(stringBytes); + } + + /** + * Original deserializeSizedString() method used in various transaction types + * @param byteBuffer + * @param maxSize + * @return + * @throws TransformationException + */ + public static String deserializeSizedString(ByteBuffer byteBuffer, int maxSize) throws TransformationException { + int size = byteBuffer.getInt(); + if (size > maxSize) + throw new TransformationException("Serialized string too long"); + + if (size > byteBuffer.remaining()) + throw new TransformationException("Byte data too short for serialized string"); + + byte[] bytes = new byte[size]; + byteBuffer.get(bytes); + + return new String(bytes, StandardCharsets.UTF_8); + } + + /** + * Alternate version of serializeSizedString() added for ARBITRARY transactions. + * These two methods can ultimately be merged together once unit tests can + * confirm that they process data identically. + * @param bytes + * @param string + * @throws UnsupportedEncodingException + * @throws IOException + */ + public static void serializeSizedStringV2(ByteArrayOutputStream bytes, String string) throws UnsupportedEncodingException, IOException { byte[] stringBytes = null; int stringBytesLength = 0; @@ -114,7 +157,17 @@ public class Serialization { } } - public static String deserializeSizedString(ByteBuffer byteBuffer, int maxSize) throws TransformationException { + /** + * Alternate version of serializeSizedString() added for ARBITRARY transactions. + * The main difference is that blank strings are returned as null. + * These two methods can ultimately be merged together once any differences are + * solved, and unit tests can confirm that they process data identically. + * @param byteBuffer + * @param maxSize + * @return + * @throws TransformationException + */ + public static String deserializeSizedStringV2(ByteBuffer byteBuffer, int maxSize) throws TransformationException { int size = byteBuffer.getInt(); if (size > maxSize) throw new TransformationException("Serialized string too long");