Add limits when deserializing BigDecimal
and BigInteger
(#2510)
* Add limits when deserializing `BigDecimal` and `BigInteger` * Use assertThrows * Don't check number limits in JsonReader
This commit is contained in:
parent
802476adc1
commit
6a9d240f78
@ -17,6 +17,7 @@
|
||||
package com.google.gson;
|
||||
|
||||
import com.google.gson.internal.LazilyParsedNumber;
|
||||
import com.google.gson.internal.NumberLimits;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Objects;
|
||||
@ -172,7 +173,7 @@ public final class JsonPrimitive extends JsonElement {
|
||||
*/
|
||||
@Override
|
||||
public BigDecimal getAsBigDecimal() {
|
||||
return value instanceof BigDecimal ? (BigDecimal) value : new BigDecimal(getAsString());
|
||||
return value instanceof BigDecimal ? (BigDecimal) value : NumberLimits.parseBigDecimal(getAsString());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -184,7 +185,7 @@ public final class JsonPrimitive extends JsonElement {
|
||||
? (BigInteger) value
|
||||
: isIntegral(this)
|
||||
? BigInteger.valueOf(this.getAsNumber().longValue())
|
||||
: new BigInteger(this.getAsString());
|
||||
: NumberLimits.parseBigInteger(this.getAsString());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -17,6 +17,7 @@
|
||||
package com.google.gson;
|
||||
|
||||
import com.google.gson.internal.LazilyParsedNumber;
|
||||
import com.google.gson.internal.NumberLimits;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.MalformedJsonException;
|
||||
import java.io.IOException;
|
||||
@ -89,7 +90,7 @@ public enum ToNumberPolicy implements ToNumberStrategy {
|
||||
@Override public BigDecimal readNumber(JsonReader in) throws IOException {
|
||||
String value = in.nextString();
|
||||
try {
|
||||
return new BigDecimal(value);
|
||||
return NumberLimits.parseBigDecimal(value);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new JsonParseException("Cannot parse " + value + "; at path " + in.getPreviousPath(), e);
|
||||
}
|
||||
|
@ -35,6 +35,10 @@ public final class LazilyParsedNumber extends Number {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
private BigDecimal asBigDecimal() {
|
||||
return NumberLimits.parseBigDecimal(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int intValue() {
|
||||
try {
|
||||
@ -43,7 +47,7 @@ public final class LazilyParsedNumber extends Number {
|
||||
try {
|
||||
return (int) Long.parseLong(value);
|
||||
} catch (NumberFormatException nfe) {
|
||||
return new BigDecimal(value).intValue();
|
||||
return asBigDecimal().intValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -53,7 +57,7 @@ public final class LazilyParsedNumber extends Number {
|
||||
try {
|
||||
return Long.parseLong(value);
|
||||
} catch (NumberFormatException e) {
|
||||
return new BigDecimal(value).longValue();
|
||||
return asBigDecimal().longValue();
|
||||
}
|
||||
}
|
||||
|
||||
@ -78,7 +82,7 @@ public final class LazilyParsedNumber extends Number {
|
||||
* deserialize it.
|
||||
*/
|
||||
private Object writeReplace() throws ObjectStreamException {
|
||||
return new BigDecimal(value);
|
||||
return asBigDecimal();
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream in) throws IOException {
|
||||
|
@ -0,0 +1,37 @@
|
||||
package com.google.gson.internal;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* This class enforces limits on numbers parsed from JSON to avoid potential performance
|
||||
* problems when extremely large numbers are used.
|
||||
*/
|
||||
public class NumberLimits {
|
||||
private NumberLimits() {
|
||||
}
|
||||
|
||||
private static final int MAX_NUMBER_STRING_LENGTH = 10_000;
|
||||
|
||||
private static void checkNumberStringLength(String s) {
|
||||
if (s.length() > MAX_NUMBER_STRING_LENGTH) {
|
||||
throw new NumberFormatException("Number string too large: " + s.substring(0, 30) + "...");
|
||||
}
|
||||
}
|
||||
|
||||
public static BigDecimal parseBigDecimal(String s) throws NumberFormatException {
|
||||
checkNumberStringLength(s);
|
||||
BigDecimal decimal = new BigDecimal(s);
|
||||
|
||||
// Cast to long to avoid issues with abs when value is Integer.MIN_VALUE
|
||||
if (Math.abs((long) decimal.scale()) >= 10_000) {
|
||||
throw new NumberFormatException("Number has unsupported scale: " + s);
|
||||
}
|
||||
return decimal;
|
||||
}
|
||||
|
||||
public static BigInteger parseBigInteger(String s) throws NumberFormatException {
|
||||
checkNumberStringLength(s);
|
||||
return new BigInteger(s);
|
||||
}
|
||||
}
|
@ -28,6 +28,7 @@ import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.TypeAdapterFactory;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import com.google.gson.internal.LazilyParsedNumber;
|
||||
import com.google.gson.internal.NumberLimits;
|
||||
import com.google.gson.internal.TroubleshootingGuide;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
@ -437,7 +438,7 @@ public final class TypeAdapters {
|
||||
}
|
||||
String s = in.nextString();
|
||||
try {
|
||||
return new BigDecimal(s);
|
||||
return NumberLimits.parseBigDecimal(s);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new JsonSyntaxException("Failed parsing '" + s + "' as BigDecimal; at path " + in.getPreviousPath(), e);
|
||||
}
|
||||
@ -456,7 +457,7 @@ public final class TypeAdapters {
|
||||
}
|
||||
String s = in.nextString();
|
||||
try {
|
||||
return new BigInteger(s);
|
||||
return NumberLimits.parseBigInteger(s);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new JsonSyntaxException("Failed parsing '" + s + "' as BigInteger; at path " + in.getPreviousPath(), e);
|
||||
}
|
||||
|
@ -0,0 +1,185 @@
|
||||
package com.google.gson.functional;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonParseException;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.google.gson.ToNumberPolicy;
|
||||
import com.google.gson.ToNumberStrategy;
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.internal.LazilyParsedNumber;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonToken;
|
||||
import com.google.gson.stream.MalformedJsonException;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.StringReader;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import org.junit.Test;
|
||||
|
||||
public class NumberLimitsTest {
|
||||
private static final int MAX_LENGTH = 10_000;
|
||||
|
||||
private static JsonReader jsonReader(String json) {
|
||||
return new JsonReader(new StringReader(json));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests how {@link JsonReader} behaves for large numbers.
|
||||
*
|
||||
* <p>Currently {@link JsonReader} itself does not enforce any limits.
|
||||
* The reasons for this are:
|
||||
* <ul>
|
||||
* <li>Methods such as {@link JsonReader#nextDouble()} seem to have no problem
|
||||
* parsing extremely large or small numbers (it rounds to 0 or Infinity)
|
||||
* (to be verified?; if it had performance problems with certain numbers, then
|
||||
* it would affect other parts of Gson which parse as float or double as well)
|
||||
* <li>Enforcing limits only when a JSON number is encountered would be ineffective
|
||||
* unless users explicitly call {@link JsonReader#peek()} and check if the value
|
||||
* is a JSON number. Otherwise the limits could be circumvented because
|
||||
* {@link JsonReader#nextString()} reads both strings and numbers, and for
|
||||
* JSON strings no restrictions are enforced.
|
||||
* </ul>
|
||||
*/
|
||||
@Test
|
||||
public void testJsonReader() throws IOException {
|
||||
JsonReader reader = jsonReader("1".repeat(1000));
|
||||
assertThat(reader.peek()).isEqualTo(JsonToken.NUMBER);
|
||||
assertThat(reader.nextString()).isEqualTo("1".repeat(1000));
|
||||
|
||||
JsonReader reader2 = jsonReader("1".repeat(MAX_LENGTH + 1));
|
||||
// Currently JsonReader does not recognize large JSON numbers as numbers but treats them
|
||||
// as unquoted string
|
||||
MalformedJsonException e = assertThrows(MalformedJsonException.class, () -> reader2.peek());
|
||||
assertThat(e).hasMessageThat().startsWith("Use JsonReader.setStrictness(Strictness.LENIENT) to accept malformed JSON");
|
||||
|
||||
reader = jsonReader("1e9999");
|
||||
assertThat(reader.peek()).isEqualTo(JsonToken.NUMBER);
|
||||
assertThat(reader.nextString()).isEqualTo("1e9999");
|
||||
|
||||
reader = jsonReader("1e+9999");
|
||||
assertThat(reader.peek()).isEqualTo(JsonToken.NUMBER);
|
||||
assertThat(reader.nextString()).isEqualTo("1e+9999");
|
||||
|
||||
reader = jsonReader("1e10000");
|
||||
assertThat(reader.peek()).isEqualTo(JsonToken.NUMBER);
|
||||
assertThat(reader.nextString()).isEqualTo("1e10000");
|
||||
|
||||
reader = jsonReader("1e00001");
|
||||
assertThat(reader.peek()).isEqualTo(JsonToken.NUMBER);
|
||||
assertThat(reader.nextString()).isEqualTo("1e00001");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJsonPrimitive() {
|
||||
assertThat(new JsonPrimitive("1".repeat(MAX_LENGTH)).getAsBigDecimal())
|
||||
.isEqualTo(new BigDecimal("1".repeat(MAX_LENGTH)));
|
||||
assertThat(new JsonPrimitive("1e9999").getAsBigDecimal())
|
||||
.isEqualTo(new BigDecimal("1e9999"));
|
||||
assertThat(new JsonPrimitive("1e-9999").getAsBigDecimal())
|
||||
.isEqualTo(new BigDecimal("1e-9999"));
|
||||
|
||||
NumberFormatException e = assertThrows(NumberFormatException.class,
|
||||
() -> new JsonPrimitive("1".repeat(MAX_LENGTH + 1)).getAsBigDecimal());
|
||||
assertThat(e).hasMessageThat().isEqualTo("Number string too large: 111111111111111111111111111111...");
|
||||
|
||||
e = assertThrows(NumberFormatException.class,
|
||||
() -> new JsonPrimitive("1e10000").getAsBigDecimal());
|
||||
assertThat(e).hasMessageThat().isEqualTo("Number has unsupported scale: 1e10000");
|
||||
|
||||
e = assertThrows(NumberFormatException.class,
|
||||
() -> new JsonPrimitive("1e-10000").getAsBigDecimal());
|
||||
assertThat(e).hasMessageThat().isEqualTo("Number has unsupported scale: 1e-10000");
|
||||
|
||||
|
||||
assertThat(new JsonPrimitive("1".repeat(MAX_LENGTH)).getAsBigInteger())
|
||||
.isEqualTo(new BigInteger("1".repeat(MAX_LENGTH)));
|
||||
|
||||
e = assertThrows(NumberFormatException.class,
|
||||
() -> new JsonPrimitive("1".repeat(MAX_LENGTH + 1)).getAsBigInteger());
|
||||
assertThat(e).hasMessageThat().isEqualTo("Number string too large: 111111111111111111111111111111...");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToNumberPolicy() throws IOException {
|
||||
ToNumberStrategy strategy = ToNumberPolicy.BIG_DECIMAL;
|
||||
|
||||
assertThat(strategy.readNumber(jsonReader("\"" + "1".repeat(MAX_LENGTH) + "\"")))
|
||||
.isEqualTo(new BigDecimal("1".repeat(MAX_LENGTH)));
|
||||
assertThat(strategy.readNumber(jsonReader("1e9999")))
|
||||
.isEqualTo(new BigDecimal("1e9999"));
|
||||
|
||||
|
||||
JsonParseException e = assertThrows(JsonParseException.class,
|
||||
() -> strategy.readNumber(jsonReader("\"" + "1".repeat(MAX_LENGTH + 1) + "\"")));
|
||||
assertThat(e).hasMessageThat().isEqualTo("Cannot parse " + "1".repeat(MAX_LENGTH + 1) + "; at path $");
|
||||
assertThat(e).hasCauseThat().hasMessageThat().isEqualTo("Number string too large: 111111111111111111111111111111...");
|
||||
|
||||
e = assertThrows(JsonParseException.class, () -> strategy.readNumber(jsonReader("\"1e10000\"")));
|
||||
assertThat(e).hasMessageThat().isEqualTo("Cannot parse 1e10000; at path $");
|
||||
assertThat(e).hasCauseThat().hasMessageThat().isEqualTo("Number has unsupported scale: 1e10000");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLazilyParsedNumber() throws IOException {
|
||||
assertThat(new LazilyParsedNumber("1".repeat(MAX_LENGTH)).intValue())
|
||||
.isEqualTo(new BigDecimal("1".repeat(MAX_LENGTH)).intValue());
|
||||
assertThat(new LazilyParsedNumber("1e9999").intValue())
|
||||
.isEqualTo(new BigDecimal("1e9999").intValue());
|
||||
|
||||
NumberFormatException e = assertThrows(NumberFormatException.class,
|
||||
() -> new LazilyParsedNumber("1".repeat(MAX_LENGTH + 1)).intValue());
|
||||
assertThat(e).hasMessageThat().isEqualTo("Number string too large: 111111111111111111111111111111...");
|
||||
|
||||
e = assertThrows(NumberFormatException.class,
|
||||
() -> new LazilyParsedNumber("1e10000").intValue());
|
||||
assertThat(e).hasMessageThat().isEqualTo("Number has unsupported scale: 1e10000");
|
||||
|
||||
e = assertThrows(NumberFormatException.class,
|
||||
() -> new LazilyParsedNumber("1e10000").longValue());
|
||||
assertThat(e).hasMessageThat().isEqualTo("Number has unsupported scale: 1e10000");
|
||||
|
||||
ObjectOutputStream objOut = new ObjectOutputStream(OutputStream.nullOutputStream());
|
||||
// Number is serialized as BigDecimal; should also enforce limits during this conversion
|
||||
e = assertThrows(NumberFormatException.class, () -> objOut.writeObject(new LazilyParsedNumber("1e10000")));
|
||||
assertThat(e).hasMessageThat().isEqualTo("Number has unsupported scale: 1e10000");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBigDecimalAdapter() throws IOException {
|
||||
TypeAdapter<BigDecimal> adapter = new Gson().getAdapter(BigDecimal.class);
|
||||
|
||||
assertThat(adapter.fromJson("\"" + "1".repeat(MAX_LENGTH) + "\""))
|
||||
.isEqualTo(new BigDecimal("1".repeat(MAX_LENGTH)));
|
||||
assertThat(adapter.fromJson("\"1e9999\""))
|
||||
.isEqualTo(new BigDecimal("1e9999"));
|
||||
|
||||
JsonSyntaxException e = assertThrows(JsonSyntaxException.class,
|
||||
() -> adapter.fromJson("\"" + "1".repeat(MAX_LENGTH + 1) + "\""));
|
||||
assertThat(e).hasMessageThat().isEqualTo("Failed parsing '" + "1".repeat(MAX_LENGTH + 1) + "' as BigDecimal; at path $");
|
||||
assertThat(e).hasCauseThat().hasMessageThat().isEqualTo("Number string too large: 111111111111111111111111111111...");
|
||||
|
||||
e = assertThrows(JsonSyntaxException.class,
|
||||
() -> adapter.fromJson("\"1e10000\""));
|
||||
assertThat(e).hasMessageThat().isEqualTo("Failed parsing '1e10000' as BigDecimal; at path $");
|
||||
assertThat(e).hasCauseThat().hasMessageThat().isEqualTo("Number has unsupported scale: 1e10000");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBigIntegerAdapter() throws IOException {
|
||||
TypeAdapter<BigInteger> adapter = new Gson().getAdapter(BigInteger.class);
|
||||
|
||||
assertThat(adapter.fromJson("\"" + "1".repeat(MAX_LENGTH) + "\""))
|
||||
.isEqualTo(new BigInteger("1".repeat(MAX_LENGTH)));
|
||||
|
||||
JsonSyntaxException e = assertThrows(JsonSyntaxException.class,
|
||||
() -> adapter.fromJson("\"" + "1".repeat(MAX_LENGTH + 1) + "\""));
|
||||
assertThat(e).hasMessageThat().isEqualTo("Failed parsing '" + "1".repeat(MAX_LENGTH + 1) + "' as BigInteger; at path $");
|
||||
assertThat(e).hasCauseThat().hasMessageThat().isEqualTo("Number string too large: 111111111111111111111111111111...");
|
||||
}
|
||||
}
|
@ -17,6 +17,7 @@
|
||||
package com.google.gson.functional;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static org.junit.Assert.assertThrows;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
@ -88,26 +89,14 @@ public class PrimitiveTest {
|
||||
|
||||
@Test
|
||||
public void testByteDeserializationLossy() {
|
||||
try {
|
||||
gson.fromJson("-129", byte.class);
|
||||
fail();
|
||||
} catch (JsonSyntaxException e) {
|
||||
assertThat(e).hasMessageThat().isEqualTo("Lossy conversion from -129 to byte; at path $");
|
||||
}
|
||||
JsonSyntaxException e = assertThrows(JsonSyntaxException.class, () -> gson.fromJson("-129", byte.class));
|
||||
assertThat(e).hasMessageThat().isEqualTo("Lossy conversion from -129 to byte; at path $");
|
||||
|
||||
try {
|
||||
gson.fromJson("256", byte.class);
|
||||
fail();
|
||||
} catch (JsonSyntaxException e) {
|
||||
assertThat(e).hasMessageThat().isEqualTo("Lossy conversion from 256 to byte; at path $");
|
||||
}
|
||||
e = assertThrows(JsonSyntaxException.class, () -> gson.fromJson("256", byte.class));
|
||||
assertThat(e).hasMessageThat().isEqualTo("Lossy conversion from 256 to byte; at path $");
|
||||
|
||||
try {
|
||||
gson.fromJson("2147483648", byte.class);
|
||||
fail();
|
||||
} catch (JsonSyntaxException e) {
|
||||
assertThat(e).hasMessageThat().isEqualTo("java.lang.NumberFormatException: Expected an int but was 2147483648 at line 1 column 11 path $");
|
||||
}
|
||||
e = assertThrows(JsonSyntaxException.class, () -> gson.fromJson("2147483648", byte.class));
|
||||
assertThat(e).hasMessageThat().isEqualTo("java.lang.NumberFormatException: Expected an int but was 2147483648 at line 1 column 11 path $");
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -136,26 +125,14 @@ public class PrimitiveTest {
|
||||
|
||||
@Test
|
||||
public void testShortDeserializationLossy() {
|
||||
try {
|
||||
gson.fromJson("-32769", short.class);
|
||||
fail();
|
||||
} catch (JsonSyntaxException e) {
|
||||
assertThat(e).hasMessageThat().isEqualTo("Lossy conversion from -32769 to short; at path $");
|
||||
}
|
||||
JsonSyntaxException e = assertThrows(JsonSyntaxException.class, () -> gson.fromJson("-32769", short.class));
|
||||
assertThat(e).hasMessageThat().isEqualTo("Lossy conversion from -32769 to short; at path $");
|
||||
|
||||
try {
|
||||
gson.fromJson("65536", short.class);
|
||||
fail();
|
||||
} catch (JsonSyntaxException e) {
|
||||
assertThat(e).hasMessageThat().isEqualTo("Lossy conversion from 65536 to short; at path $");
|
||||
}
|
||||
e = assertThrows(JsonSyntaxException.class, () -> gson.fromJson("65536", short.class));
|
||||
assertThat(e).hasMessageThat().isEqualTo("Lossy conversion from 65536 to short; at path $");
|
||||
|
||||
try {
|
||||
gson.fromJson("2147483648", short.class);
|
||||
fail();
|
||||
} catch (JsonSyntaxException e) {
|
||||
assertThat(e).hasMessageThat().isEqualTo("java.lang.NumberFormatException: Expected an int but was 2147483648 at line 1 column 11 path $");
|
||||
}
|
||||
e = assertThrows(JsonSyntaxException.class, () -> gson.fromJson("2147483648", short.class));
|
||||
assertThat(e).hasMessageThat().isEqualTo("java.lang.NumberFormatException: Expected an int but was 2147483648 at line 1 column 11 path $");
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -768,10 +745,7 @@ public class PrimitiveTest {
|
||||
assertThat(gson.fromJson("UnquotedSingleWord", String.class)).isEqualTo("UnquotedSingleWord");
|
||||
|
||||
String value = "String Blah Blah Blah...1, 2, 3";
|
||||
try {
|
||||
gson.fromJson(value, String.class);
|
||||
fail();
|
||||
} catch (JsonSyntaxException expected) { }
|
||||
assertThrows(JsonSyntaxException.class, () -> gson.fromJson(value, String.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -805,162 +779,102 @@ public class PrimitiveTest {
|
||||
|
||||
@Test
|
||||
public void testDeserializeJsonObjectAsLongPrimitive() {
|
||||
try {
|
||||
gson.fromJson("{'abc':1}", long.class);
|
||||
fail();
|
||||
} catch (JsonSyntaxException expected) {}
|
||||
assertThrows(JsonSyntaxException.class, () -> gson.fromJson("{'abc':1}", long.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeserializeJsonArrayAsLongWrapper() {
|
||||
try {
|
||||
gson.fromJson("[1,2,3]", Long.class);
|
||||
fail();
|
||||
} catch (JsonSyntaxException expected) {}
|
||||
assertThrows(JsonSyntaxException.class, () -> gson.fromJson("[1,2,3]", Long.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeserializeJsonArrayAsInt() {
|
||||
try {
|
||||
gson.fromJson("[1, 2, 3, 4]", int.class);
|
||||
fail();
|
||||
} catch (JsonSyntaxException expected) {}
|
||||
assertThrows(JsonSyntaxException.class, () -> gson.fromJson("[1, 2, 3, 4]", int.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeserializeJsonObjectAsInteger() {
|
||||
try {
|
||||
gson.fromJson("{}", Integer.class);
|
||||
fail();
|
||||
} catch (JsonSyntaxException expected) {}
|
||||
assertThrows(JsonSyntaxException.class, () -> gson.fromJson("{}", Integer.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeserializeJsonObjectAsShortPrimitive() {
|
||||
try {
|
||||
gson.fromJson("{'abc':1}", short.class);
|
||||
fail();
|
||||
} catch (JsonSyntaxException expected) {}
|
||||
assertThrows(JsonSyntaxException.class, () -> gson.fromJson("{'abc':1}", short.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeserializeJsonArrayAsShortWrapper() {
|
||||
try {
|
||||
gson.fromJson("['a','b']", Short.class);
|
||||
fail();
|
||||
} catch (JsonSyntaxException expected) {}
|
||||
assertThrows(JsonSyntaxException.class, () -> gson.fromJson("['a','b']", Short.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeserializeJsonArrayAsDoublePrimitive() {
|
||||
try {
|
||||
gson.fromJson("[1,2]", double.class);
|
||||
fail();
|
||||
} catch (JsonSyntaxException expected) {}
|
||||
assertThrows(JsonSyntaxException.class, () -> gson.fromJson("[1,2]", double.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeserializeJsonObjectAsDoubleWrapper() {
|
||||
try {
|
||||
gson.fromJson("{'abc':1}", Double.class);
|
||||
fail();
|
||||
} catch (JsonSyntaxException expected) {}
|
||||
assertThrows(JsonSyntaxException.class, () -> gson.fromJson("{'abc':1}", Double.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeserializeJsonObjectAsFloatPrimitive() {
|
||||
try {
|
||||
gson.fromJson("{'abc':1}", float.class);
|
||||
fail();
|
||||
} catch (JsonSyntaxException expected) {}
|
||||
assertThrows(JsonSyntaxException.class, () -> gson.fromJson("{'abc':1}", float.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeserializeJsonArrayAsFloatWrapper() {
|
||||
try {
|
||||
gson.fromJson("[1,2,3]", Float.class);
|
||||
fail();
|
||||
} catch (JsonSyntaxException expected) {}
|
||||
assertThrows(JsonSyntaxException.class, () -> gson.fromJson("[1,2,3]", Float.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeserializeJsonObjectAsBytePrimitive() {
|
||||
try {
|
||||
gson.fromJson("{'abc':1}", byte.class);
|
||||
fail();
|
||||
} catch (JsonSyntaxException expected) {}
|
||||
assertThrows(JsonSyntaxException.class, () -> gson.fromJson("{'abc':1}", byte.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeserializeJsonArrayAsByteWrapper() {
|
||||
try {
|
||||
gson.fromJson("[1,2,3,4]", Byte.class);
|
||||
fail();
|
||||
} catch (JsonSyntaxException expected) {}
|
||||
assertThrows(JsonSyntaxException.class, () -> gson.fromJson("[1,2,3,4]", Byte.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeserializeJsonObjectAsBooleanPrimitive() {
|
||||
try {
|
||||
gson.fromJson("{'abc':1}", boolean.class);
|
||||
fail();
|
||||
} catch (JsonSyntaxException expected) {}
|
||||
assertThrows(JsonSyntaxException.class, () -> gson.fromJson("{'abc':1}", boolean.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeserializeJsonArrayAsBooleanWrapper() {
|
||||
try {
|
||||
gson.fromJson("[1,2,3,4]", Boolean.class);
|
||||
fail();
|
||||
} catch (JsonSyntaxException expected) {}
|
||||
assertThrows(JsonSyntaxException.class, () -> gson.fromJson("[1,2,3,4]", Boolean.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeserializeJsonArrayAsBigDecimal() {
|
||||
try {
|
||||
gson.fromJson("[1,2,3,4]", BigDecimal.class);
|
||||
fail();
|
||||
} catch (JsonSyntaxException expected) {}
|
||||
assertThrows(JsonSyntaxException.class, () -> gson.fromJson("[1,2,3,4]", BigDecimal.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeserializeJsonObjectAsBigDecimal() {
|
||||
try {
|
||||
gson.fromJson("{'a':1}", BigDecimal.class);
|
||||
fail();
|
||||
} catch (JsonSyntaxException expected) {}
|
||||
assertThrows(JsonSyntaxException.class, () -> gson.fromJson("{'a':1}", BigDecimal.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeserializeJsonArrayAsBigInteger() {
|
||||
try {
|
||||
gson.fromJson("[1,2,3,4]", BigInteger.class);
|
||||
fail();
|
||||
} catch (JsonSyntaxException expected) {}
|
||||
assertThrows(JsonSyntaxException.class, () -> gson.fromJson("[1,2,3,4]", BigInteger.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeserializeJsonObjectAsBigInteger() {
|
||||
try {
|
||||
gson.fromJson("{'c':2}", BigInteger.class);
|
||||
fail();
|
||||
} catch (JsonSyntaxException expected) {}
|
||||
assertThrows(JsonSyntaxException.class, () -> gson.fromJson("{'c':2}", BigInteger.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeserializeJsonArrayAsNumber() {
|
||||
try {
|
||||
gson.fromJson("[1,2,3,4]", Number.class);
|
||||
fail();
|
||||
} catch (JsonSyntaxException expected) {}
|
||||
assertThrows(JsonSyntaxException.class, () -> gson.fromJson("[1,2,3,4]", Number.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeserializeJsonObjectAsNumber() {
|
||||
try {
|
||||
gson.fromJson("{'c':2}", Number.class);
|
||||
fail();
|
||||
} catch (JsonSyntaxException expected) {}
|
||||
assertThrows(JsonSyntaxException.class, () -> gson.fromJson("{'c':2}", Number.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -970,53 +884,30 @@ public class PrimitiveTest {
|
||||
|
||||
@Test
|
||||
public void testDeserializingNonZeroDecimalPointValuesAsIntegerFails() {
|
||||
try {
|
||||
gson.fromJson("1.02", Byte.class);
|
||||
fail();
|
||||
} catch (JsonSyntaxException expected) {
|
||||
}
|
||||
try {
|
||||
gson.fromJson("1.02", Short.class);
|
||||
fail();
|
||||
} catch (JsonSyntaxException expected) {
|
||||
}
|
||||
try {
|
||||
gson.fromJson("1.02", Integer.class);
|
||||
fail();
|
||||
} catch (JsonSyntaxException expected) {
|
||||
}
|
||||
try {
|
||||
gson.fromJson("1.02", Long.class);
|
||||
fail();
|
||||
} catch (JsonSyntaxException expected) {
|
||||
}
|
||||
assertThrows(JsonSyntaxException.class, () -> gson.fromJson("1.02", Byte.class));
|
||||
assertThrows(JsonSyntaxException.class, () -> gson.fromJson("1.02", Short.class));
|
||||
assertThrows(JsonSyntaxException.class, () -> gson.fromJson("1.02", Integer.class));
|
||||
assertThrows(JsonSyntaxException.class, () -> gson.fromJson("1.02", Long.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeserializingBigDecimalAsIntegerFails() {
|
||||
try {
|
||||
gson.fromJson("-122.08e-213", Integer.class);
|
||||
fail();
|
||||
} catch (JsonSyntaxException expected) {
|
||||
}
|
||||
JsonSyntaxException e = assertThrows(JsonSyntaxException.class, () -> gson.fromJson("-122.08e-213", Integer.class));
|
||||
assertThat(e).hasCauseThat().hasMessageThat().isEqualTo("Expected an int but was -122.08e-213 at line 1 column 13 path $");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeserializingBigIntegerAsInteger() {
|
||||
try {
|
||||
gson.fromJson("12121211243123245845384534687435634558945453489543985435", Integer.class);
|
||||
fail();
|
||||
} catch (JsonSyntaxException expected) {
|
||||
}
|
||||
String number = "12121211243123245845384534687435634558945453489543985435";
|
||||
JsonSyntaxException e = assertThrows(JsonSyntaxException.class, () -> gson.fromJson(number, Integer.class));
|
||||
assertThat(e).hasCauseThat().hasMessageThat().isEqualTo("Expected an int but was " + number + " at line 1 column 57 path $");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeserializingBigIntegerAsLong() {
|
||||
try {
|
||||
gson.fromJson("12121211243123245845384534687435634558945453489543985435", Long.class);
|
||||
fail();
|
||||
} catch (JsonSyntaxException expected) {
|
||||
}
|
||||
String number = "12121211243123245845384534687435634558945453489543985435";
|
||||
JsonSyntaxException e = assertThrows(JsonSyntaxException.class, () -> gson.fromJson(number, Long.class));
|
||||
assertThat(e).hasCauseThat().hasMessageThat().isEqualTo("Expected a long but was " + number + " at line 1 column 57 path $");
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -1031,27 +922,9 @@ public class PrimitiveTest {
|
||||
assertThat(gson.fromJson("122.08e-2132", double.class)).isEqualTo(0.0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeserializingBigDecimalAsFloat() {
|
||||
String json = "-122.08e-2132332";
|
||||
float actual = gson.fromJson(json, float.class);
|
||||
assertThat(actual).isEqualTo(-0.0f);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeserializingBigDecimalAsDouble() {
|
||||
String json = "-122.08e-2132332";
|
||||
double actual = gson.fromJson(json, double.class);
|
||||
assertThat(actual).isEqualTo(-0.0d);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeserializingBigDecimalAsBigIntegerFails() {
|
||||
try {
|
||||
gson.fromJson("-122.08e-213", BigInteger.class);
|
||||
fail();
|
||||
} catch (JsonSyntaxException expected) {
|
||||
}
|
||||
assertThrows(JsonSyntaxException.class, () -> gson.fromJson("-122.08e-213", BigInteger.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
Loading…
Reference in New Issue
Block a user