From c8214205715256c53c5c9d868fe276a6f6a3e3cd Mon Sep 17 00:00:00 2001 From: Querz Date: Tue, 18 Dec 2018 10:24:30 +0100 Subject: [PATCH] improve ArrayTag type safety --- src/main/java/net/querz/nbt/ArrayTag.java | 17 +++---- src/main/java/net/querz/nbt/ByteArrayTag.java | 6 ++- src/main/java/net/querz/nbt/IntArrayTag.java | 6 ++- src/main/java/net/querz/nbt/LongArrayTag.java | 6 ++- .../net/querz/nbt/custom/ShortArrayTag.java | 6 ++- .../java/net/querz/nbt/ByteArrayTagTest.java | 44 ++++++++++++++++++- .../java/net/querz/nbt/IntArrayTagTest.java | 1 - .../java/net/querz/nbt/LongArrayTagTest.java | 1 - 8 files changed, 66 insertions(+), 21 deletions(-) diff --git a/src/main/java/net/querz/nbt/ArrayTag.java b/src/main/java/net/querz/nbt/ArrayTag.java index 8269fe65..46016a78 100644 --- a/src/main/java/net/querz/nbt/ArrayTag.java +++ b/src/main/java/net/querz/nbt/ArrayTag.java @@ -9,10 +9,11 @@ * */ public abstract class ArrayTag extends Tag { - public ArrayTag() {} - public ArrayTag(T value) { - super(value); + if (!value.getClass().isArray()) { + throw new UnsupportedOperationException("type of array tag must be an array"); + } + setValue(value); } public int length() { @@ -31,7 +32,7 @@ public void setValue(T value) { @Override public String valueToString(int depth) { - return arrayToString(getValue(), "", ""); + return arrayToString("", ""); } @Override @@ -42,14 +43,10 @@ public int compareTo(Tag other) { return Integer.compare(Array.getLength(getValue()), Array.getLength(other.getValue())); } - protected String arrayToString(T array, String prefix, String suffix) { - if (array == null || !array.getClass().isArray()) { - throw new UnsupportedOperationException("cannot convert non-array to String"); - } - + protected String arrayToString(String prefix, String suffix) { StringBuilder sb = new StringBuilder("[").append(prefix).append("".equals(prefix) ? "" : ";"); for (int i = 0; i < length(); i++) { - sb.append(i == 0 ? "" : ",").append(Array.get(array, i)).append(suffix); + sb.append(i == 0 ? "" : ",").append(Array.get(getValue(), i)).append(suffix); } sb.append("]"); return sb.toString(); diff --git a/src/main/java/net/querz/nbt/ByteArrayTag.java b/src/main/java/net/querz/nbt/ByteArrayTag.java index 0a612cf4..8b8c68da 100644 --- a/src/main/java/net/querz/nbt/ByteArrayTag.java +++ b/src/main/java/net/querz/nbt/ByteArrayTag.java @@ -7,7 +7,9 @@ public class ByteArrayTag extends ArrayTag { - public ByteArrayTag() {} + public ByteArrayTag() { + super(new byte[0]); + } public ByteArrayTag(byte[] value) { super(value); @@ -33,7 +35,7 @@ public void deserializeValue(DataInputStream dis, int depth) throws IOException @Override public String valueToTagString(int depth) { - return arrayToString(getValue(), "B", "b"); + return arrayToString("B", "b"); } @Override diff --git a/src/main/java/net/querz/nbt/IntArrayTag.java b/src/main/java/net/querz/nbt/IntArrayTag.java index 30a2f7f5..647e83b8 100644 --- a/src/main/java/net/querz/nbt/IntArrayTag.java +++ b/src/main/java/net/querz/nbt/IntArrayTag.java @@ -7,7 +7,9 @@ public class IntArrayTag extends ArrayTag { - public IntArrayTag() {} + public IntArrayTag() { + super(new int[0]); + } public IntArrayTag(int[] value) { super(value); @@ -37,7 +39,7 @@ public void deserializeValue(DataInputStream dis, int depth) throws IOException @Override public String valueToTagString(int depth) { - return arrayToString(getValue(), "I", ""); + return arrayToString("I", ""); } @Override diff --git a/src/main/java/net/querz/nbt/LongArrayTag.java b/src/main/java/net/querz/nbt/LongArrayTag.java index c3e90d7e..096c28bd 100644 --- a/src/main/java/net/querz/nbt/LongArrayTag.java +++ b/src/main/java/net/querz/nbt/LongArrayTag.java @@ -7,7 +7,9 @@ public class LongArrayTag extends ArrayTag { - public LongArrayTag() {} + public LongArrayTag() { + super(new long[0]); + } public LongArrayTag(long[] value) { super(value); @@ -37,7 +39,7 @@ public void deserializeValue(DataInputStream dis, int depth) throws IOException @Override public String valueToTagString(int depth) { - return arrayToString(getValue(), "L", "l"); + return arrayToString("L", "l"); } @Override diff --git a/src/main/java/net/querz/nbt/custom/ShortArrayTag.java b/src/main/java/net/querz/nbt/custom/ShortArrayTag.java index 4b33c307..7c98bf60 100644 --- a/src/main/java/net/querz/nbt/custom/ShortArrayTag.java +++ b/src/main/java/net/querz/nbt/custom/ShortArrayTag.java @@ -13,7 +13,9 @@ public static void register() { TagFactory.registerCustomTag(100, ShortArrayTag::new, ShortArrayTag.class); } - public ShortArrayTag() {} + public ShortArrayTag() { + super(new short[0]); + } public ShortArrayTag(short[] value) { super(value); @@ -43,7 +45,7 @@ public void deserializeValue(DataInputStream dis, int depth) throws IOException @Override public String valueToTagString(int depth) { - return arrayToString(getValue(), "S", "s"); + return arrayToString("S", "s"); } @Override diff --git a/src/test/java/net/querz/nbt/ByteArrayTagTest.java b/src/test/java/net/querz/nbt/ByteArrayTagTest.java index 8274f3e6..157ba3cb 100644 --- a/src/test/java/net/querz/nbt/ByteArrayTagTest.java +++ b/src/test/java/net/querz/nbt/ByteArrayTagTest.java @@ -1,5 +1,7 @@ package net.querz.nbt; +import java.io.DataInputStream; +import java.io.DataOutputStream; import java.util.Arrays; public class ByteArrayTagTest extends NBTTestCase { @@ -10,7 +12,6 @@ public void testStringConversion() { assertEquals(7, t.getID()); assertEquals("[B;-128b,0b,127b]", t.toTagString()); assertEquals("{\"type\":\"" + t.getClass().getSimpleName() + "\",\"value\":[-128,0,127]}", t.toString()); - assertThrowsRuntimeException(() -> t.arrayToString(null, "", ""), UnsupportedOperationException.class); } public void testEquals() { @@ -48,4 +49,45 @@ public void testCompareTo() { assertTrue(0 > t4.compareTo(t)); assertThrowsRuntimeException(() -> t.compareTo(null), IllegalArgumentException.class); } + + public void testInvalidType() { + assertThrowsRuntimeException(NotAnArrayTag::new, UnsupportedOperationException.class); + assertThrowsRuntimeException(() -> new NotAnArrayTag("test"), UnsupportedOperationException.class); + } + + public class NotAnArrayTag extends ArrayTag { + + public NotAnArrayTag() { + super(""); + } + + public NotAnArrayTag(String value) { + super(value); + } + + @Override + protected String getEmptyValue() { + return ""; + } + + @Override + public void serializeValue(DataOutputStream dos, int depth) { + throw new UnsupportedOperationException("goddammit, this is a test class, you don't want to save it."); + } + + @Override + public void deserializeValue(DataInputStream dis, int depth) { + throw new UnsupportedOperationException("goddammit, this is a test class, you don't want to load it."); + } + + @Override + public String valueToTagString(int depth) { + return escapeString(getValue(), true); + } + + @Override + public NotAnArrayTag clone() { + return new NotAnArrayTag(getName()); + } + } } diff --git a/src/test/java/net/querz/nbt/IntArrayTagTest.java b/src/test/java/net/querz/nbt/IntArrayTagTest.java index 9c72091d..e369896e 100644 --- a/src/test/java/net/querz/nbt/IntArrayTagTest.java +++ b/src/test/java/net/querz/nbt/IntArrayTagTest.java @@ -10,7 +10,6 @@ public void testStringConversion() { assertEquals(11, t.getID()); assertEquals("[I;-2147483648,0,2147483647]", t.toTagString()); assertEquals("{\"type\":\"" + t.getClass().getSimpleName() + "\",\"value\":[-2147483648,0,2147483647]}", t.toString()); - assertThrowsRuntimeException(() -> t.arrayToString(null, "", ""), UnsupportedOperationException.class); } public void testEquals() { diff --git a/src/test/java/net/querz/nbt/LongArrayTagTest.java b/src/test/java/net/querz/nbt/LongArrayTagTest.java index 150b2df7..8d8e92bc 100644 --- a/src/test/java/net/querz/nbt/LongArrayTagTest.java +++ b/src/test/java/net/querz/nbt/LongArrayTagTest.java @@ -10,7 +10,6 @@ public void testStringConversion() { assertEquals(12, t.getID()); assertEquals("[L;-9223372036854775808l,0l,9223372036854775807l]", t.toTagString()); assertEquals("{\"type\":\"" + t.getClass().getSimpleName() + "\",\"value\":[-9223372036854775808,0,9223372036854775807]}", t.toString()); - assertThrowsRuntimeException(() -> t.arrayToString(null, "", ""), UnsupportedOperationException.class); } public void testEquals() {