mirror of
https://github.com/ViaVersion/ViaVersion.git
synced 2024-11-29 13:36:16 +01:00
Fix premature snbt numeric parsing
This commit is contained in:
parent
a7835650bf
commit
8104b96b8c
@ -256,64 +256,57 @@ final class TagStringReader {
|
||||
*/
|
||||
private Tag scalar() {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
boolean possiblyNumeric = true;
|
||||
int noLongerNumericAt = -1;
|
||||
while (this.buffer.hasMore()) {
|
||||
final char current = this.buffer.peek();
|
||||
if (possiblyNumeric && !Tokens.numeric(current)) {
|
||||
if (builder.length() != 0) {
|
||||
Tag result = null;
|
||||
try {
|
||||
switch (Character.toLowerCase(current)) { // try to read and return as a number
|
||||
case Tokens.TYPE_BYTE:
|
||||
result = new ByteTag(Byte.parseByte(builder.toString()));
|
||||
break;
|
||||
case Tokens.TYPE_SHORT:
|
||||
result = new ShortTag(Short.parseShort(builder.toString()));
|
||||
break;
|
||||
case Tokens.TYPE_INT:
|
||||
result = new IntTag(Integer.parseInt(builder.toString()));
|
||||
break;
|
||||
case Tokens.TYPE_LONG:
|
||||
result = new LongTag(Long.parseLong(builder.toString()));
|
||||
break;
|
||||
case Tokens.TYPE_FLOAT:
|
||||
final float floatValue = Float.parseFloat(builder.toString());
|
||||
if (!Float.isNaN(floatValue)) {
|
||||
result = new FloatTag(floatValue);
|
||||
}
|
||||
break;
|
||||
case Tokens.TYPE_DOUBLE:
|
||||
final double doubleValue = Double.parseDouble(builder.toString());
|
||||
if (!Double.isNaN(doubleValue)) {
|
||||
result = new DoubleTag(doubleValue);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} catch (final NumberFormatException ex) {
|
||||
possiblyNumeric = false; // fallback to treating as a String
|
||||
}
|
||||
if (result != null) {
|
||||
this.buffer.take();
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
char current = this.buffer.peek();
|
||||
if (current == '\\') { // escape -- we are significantly more lenient than original format at the moment
|
||||
this.buffer.advance();
|
||||
builder.append(this.buffer.take());
|
||||
current = this.buffer.take();
|
||||
} else if (Tokens.id(current)) {
|
||||
builder.append(this.buffer.take());
|
||||
this.buffer.advance();
|
||||
} else { // end of value
|
||||
break;
|
||||
}
|
||||
builder.append(current);
|
||||
if (noLongerNumericAt == -1 && !Tokens.numeric(current)) {
|
||||
noLongerNumericAt = builder.length();
|
||||
}
|
||||
// if we run out of content without an explicit value separator, then we're either an integer or string tag -- all others have a character at the end
|
||||
}
|
||||
|
||||
final int length = builder.length();
|
||||
final String built = builder.toString();
|
||||
if (possiblyNumeric) {
|
||||
if (noLongerNumericAt == length) {
|
||||
final char last = built.charAt(length - 1);
|
||||
try {
|
||||
switch (Character.toLowerCase(last)) { // try to read and return as a number
|
||||
case Tokens.TYPE_BYTE:
|
||||
return new ByteTag(Byte.parseByte(built.substring(0, length - 1)));
|
||||
case Tokens.TYPE_SHORT:
|
||||
return new ShortTag(Short.parseShort(built.substring(0, length - 1)));
|
||||
case Tokens.TYPE_INT:
|
||||
return new IntTag(Integer.parseInt(built.substring(0, length - 1)));
|
||||
case Tokens.TYPE_LONG:
|
||||
return new LongTag(Long.parseLong(built.substring(0, length - 1)));
|
||||
case Tokens.TYPE_FLOAT:
|
||||
final float floatValue = Float.parseFloat(built.substring(0, length - 1));
|
||||
if (Float.isFinite(floatValue)) { // don't accept NaN and Infinity
|
||||
return new FloatTag(floatValue);
|
||||
}
|
||||
break;
|
||||
case Tokens.TYPE_DOUBLE:
|
||||
final double doubleValue = Double.parseDouble(built.substring(0, length - 1));
|
||||
if (Double.isFinite(doubleValue)) { // don't accept NaN and Infinity
|
||||
return new DoubleTag(doubleValue);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} catch (final NumberFormatException ignored) {
|
||||
}
|
||||
} else if (noLongerNumericAt == -1) { // if we run out of content without an explicit value separator, then we're either an integer or string tag -- all others have a character at the end
|
||||
try {
|
||||
return new IntTag(Integer.parseInt(built));
|
||||
} catch (final NumberFormatException ignored) {
|
||||
// Via - don't try to parse as DoubleTag here
|
||||
} catch (final NumberFormatException ex) {
|
||||
// Via - don't try to parse as DoubleTag her
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,9 @@ public class NBTTagTest {
|
||||
readString("{id:[I;1,2,3,]}");
|
||||
readString("{id:[1,2,3,]}");
|
||||
|
||||
Assertions.assertEquals("0da", readString("{id:0da}").get("id").getValue());
|
||||
Assertions.assertEquals("NaNd", readString("{id:NaNd}").get("id").getValue());
|
||||
Assertions.assertEquals("Infinityd", readString("{id:Infinityd}").get("id").getValue());
|
||||
Assertions.assertEquals("2147483649", readString("{id:9000b,thisisastring:2147483649}").get("thisisastring").getValue());
|
||||
Assertions.assertEquals((byte) 1, readString("{thisisabyte:true}").get("thisisabyte").getValue());
|
||||
Assertions.assertEquals((byte) 0, readString("{thisisabyte:false}").get("thisisabyte").getValue());
|
||||
|
Loading…
Reference in New Issue
Block a user