Improve number strategy implementation (#1987)

* Fix GsonBuilder not copying number strategies from Gson

* Improve ToNumberPolicy exception messages
This commit is contained in:
Marcono1234 2021-10-12 01:14:47 +02:00 committed by GitHub
parent cd748df712
commit bda2e3d16a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 30 additions and 4 deletions

View File

@ -130,6 +130,8 @@ public final class GsonBuilder {
this.timeStyle = gson.timeStyle;
this.factories.addAll(gson.builderFactories);
this.hierarchyFactories.addAll(gson.builderHierarchyFactories);
this.objectToNumberStrategy = gson.objectToNumberStrategy;
this.numberToNumberStrategy = gson.numberToNumberStrategy;
}
/**

View File

@ -71,11 +71,11 @@ public enum ToNumberPolicy implements ToNumberStrategy {
try {
Double d = Double.valueOf(value);
if ((d.isInfinite() || d.isNaN()) && !in.isLenient()) {
throw new MalformedJsonException("JSON forbids NaN and infinities: " + d + in);
throw new MalformedJsonException("JSON forbids NaN and infinities: " + d + "; at path " + in.getPath());
}
return d;
} catch (NumberFormatException doubleE) {
throw new JsonParseException("Cannot parse " + value, doubleE);
throw new JsonParseException("Cannot parse " + value + "; at path " + in.getPath(), doubleE);
}
}
}
@ -91,7 +91,7 @@ public enum ToNumberPolicy implements ToNumberStrategy {
try {
return new BigDecimal(value);
} catch (NumberFormatException e) {
throw new JsonParseException("Cannot parse " + value, e);
throw new JsonParseException("Cannot parse " + value + "; at path " + in.getPath(), e);
}
}
}

View File

@ -283,7 +283,7 @@ public final class JsonTreeReader extends JsonReader {
}
@Override public String toString() {
return getClass().getSimpleName();
return getClass().getSimpleName() + locationString();
}
public void promoteNameToValue() throws IOException {

View File

@ -33,6 +33,12 @@ public class ToNumberPolicyTest extends TestCase {
strategy.readNumber(fromString("1e400"));
fail();
} catch (MalformedJsonException expected) {
assertEquals("JSON forbids NaN and infinities: Infinity at line 1 column 6 path $", expected.getMessage());
}
try {
strategy.readNumber(fromString("\"not-a-number\""));
fail();
} catch (NumberFormatException expected) {
}
}
@ -52,7 +58,15 @@ public class ToNumberPolicyTest extends TestCase {
strategy.readNumber(fromString("1e400"));
fail();
} catch (MalformedJsonException expected) {
assertEquals("JSON forbids NaN and infinities: Infinity; at path $", expected.getMessage());
}
try {
strategy.readNumber(fromString("\"not-a-number\""));
fail();
} catch (JsonParseException expected) {
assertEquals("Cannot parse not-a-number; at path $", expected.getMessage());
}
assertEquals(Double.NaN, strategy.readNumber(fromStringLenient("NaN")));
assertEquals(Double.POSITIVE_INFINITY, strategy.readNumber(fromStringLenient("Infinity")));
assertEquals(Double.NEGATIVE_INFINITY, strategy.readNumber(fromStringLenient("-Infinity")));
@ -60,16 +74,19 @@ public class ToNumberPolicyTest extends TestCase {
strategy.readNumber(fromString("NaN"));
fail();
} catch (MalformedJsonException expected) {
assertEquals("Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 1 path $", expected.getMessage());
}
try {
strategy.readNumber(fromString("Infinity"));
fail();
} catch (MalformedJsonException expected) {
assertEquals("Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 1 path $", expected.getMessage());
}
try {
strategy.readNumber(fromString("-Infinity"));
fail();
} catch (MalformedJsonException expected) {
assertEquals("Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 1 path $", expected.getMessage());
}
}
@ -78,6 +95,13 @@ public class ToNumberPolicyTest extends TestCase {
assertEquals(new BigDecimal("10.1"), strategy.readNumber(fromString("10.1")));
assertEquals(new BigDecimal("3.141592653589793238462643383279"), strategy.readNumber(fromString("3.141592653589793238462643383279")));
assertEquals(new BigDecimal("1e400"), strategy.readNumber(fromString("1e400")));
try {
strategy.readNumber(fromString("\"not-a-number\""));
fail();
} catch (JsonParseException expected) {
assertEquals("Cannot parse not-a-number; at path $", expected.getMessage());
}
}
public void testNullsAreNeverExpected() throws IOException {