Revised Gson to refuse to deserialize floating point numbers into integer types.
This is probably a break from the past: previous versions of Gson allowed truncating a floating point into a long or int. However, it wasn't consistent in this behavior. It disallowed converting a BigDecimal value into BigInteger, int or long. Refusing to deserialize such values is aligned with fail-fast approach of uncovering bugs.
This commit is contained in:
parent
ce79e16f7a
commit
0bcd1b341f
@ -213,7 +213,8 @@ public final class JsonPrimitive extends JsonElement {
|
||||
*/
|
||||
@Override
|
||||
public BigInteger getAsBigInteger() {
|
||||
return value instanceof BigInteger ? (BigInteger) value : new BigInteger(value.toString());
|
||||
return value instanceof BigInteger ?
|
||||
(BigInteger) value : new BigInteger(value.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.google.gson;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* This class holds a number value that is lazily converted to a specific number type
|
||||
*
|
||||
@ -30,12 +32,24 @@ final class LazilyParsedNumber extends Number {
|
||||
|
||||
@Override
|
||||
public int intValue() {
|
||||
try {
|
||||
return Integer.parseInt(value);
|
||||
} catch (NumberFormatException e) {
|
||||
try {
|
||||
return (int) Long.parseLong(value);
|
||||
} catch (NumberFormatException nfe) {
|
||||
return new BigInteger(value).intValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long longValue() {
|
||||
try {
|
||||
return Long.parseLong(value);
|
||||
} catch (NumberFormatException e) {
|
||||
return new BigInteger(value).longValue();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -38,6 +38,9 @@ import java.math.BigInteger;
|
||||
* @author Joel Leitch
|
||||
*/
|
||||
public class PrimitiveTest extends TestCase {
|
||||
private static final BigInteger MAX_INT_VALUE = new BigInteger("2147483647");
|
||||
private static final BigInteger MAX_LONG_VALUE = new BigInteger("9223372036854775807");
|
||||
|
||||
private Gson gson;
|
||||
|
||||
@Override
|
||||
@ -757,4 +760,68 @@ public class PrimitiveTest extends TestCase {
|
||||
fail();
|
||||
} catch (JsonSyntaxException expected) {}
|
||||
}
|
||||
|
||||
public void testDeserializingDecimalPointValuesAsIntegerFails() {
|
||||
try {
|
||||
gson.fromJson("1.0", Integer.class);
|
||||
fail();
|
||||
} catch (JsonParseException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
public void testDeserializingBigDecimalAsIntegerFails() {
|
||||
try {
|
||||
gson.fromJson("-122.08e-213", Integer.class);
|
||||
fail();
|
||||
} catch (JsonParseException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
public void testDeserializingBigIntegerAsInteger() {
|
||||
String bigIntegerValue = "12121211243123245845384534687435634558945453489543985435";
|
||||
int actual = gson.fromJson(bigIntegerValue, Integer.class);
|
||||
int expected = new BigInteger(bigIntegerValue).and(MAX_INT_VALUE).intValue();
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
public void testDeserializingBigIntegerAsLong() {
|
||||
String bigIntegerValue = "12121211243123245845384534687435634558945453489543985435";
|
||||
long actual = gson.fromJson(bigIntegerValue, long.class);
|
||||
long expected = new BigInteger(bigIntegerValue).and(MAX_LONG_VALUE).longValue();
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
|
||||
public void testDeserializingBigDecimalAsLongFails() {
|
||||
try {
|
||||
gson.fromJson("-122.08e-2132", long.class);
|
||||
fail();
|
||||
} catch (JsonParseException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
public void testDeserializingBigDecimalAsFloat() {
|
||||
String json = "-122.08e-2132332";
|
||||
float actual = gson.fromJson(json, float.class);
|
||||
assertEquals(-0.0f, actual);
|
||||
}
|
||||
|
||||
public void testDeserializingBigDecimalAsDouble() {
|
||||
String json = "-122.08e-2132332";
|
||||
double actual = gson.fromJson(json, double.class);
|
||||
assertEquals(-0.0d, actual);
|
||||
}
|
||||
|
||||
public void testDeserializingBigDecimalAsBigIntegerFails() {
|
||||
try {
|
||||
gson.fromJson("-122.08e-213", BigInteger.class);
|
||||
fail();
|
||||
} catch (JsonParseException expected) {
|
||||
}
|
||||
}
|
||||
|
||||
public void testDeserializingBigIntegerAsBigDecimal() {
|
||||
BigDecimal actual =
|
||||
gson.fromJson("12121211243123245845384534687435634558945453489543985435", BigDecimal.class);
|
||||
assertEquals("12121211243123245845384534687435634558945453489543985435", actual.toPlainString());
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user