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.timeStyle = gson.timeStyle;
this.factories.addAll(gson.builderFactories); this.factories.addAll(gson.builderFactories);
this.hierarchyFactories.addAll(gson.builderHierarchyFactories); 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 { try {
Double d = Double.valueOf(value); Double d = Double.valueOf(value);
if ((d.isInfinite() || d.isNaN()) && !in.isLenient()) { 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; return d;
} catch (NumberFormatException doubleE) { } 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 { try {
return new BigDecimal(value); return new BigDecimal(value);
} catch (NumberFormatException e) { } 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() { @Override public String toString() {
return getClass().getSimpleName(); return getClass().getSimpleName() + locationString();
} }
public void promoteNameToValue() throws IOException { public void promoteNameToValue() throws IOException {

View File

@ -33,6 +33,12 @@ public class ToNumberPolicyTest extends TestCase {
strategy.readNumber(fromString("1e400")); strategy.readNumber(fromString("1e400"));
fail(); fail();
} catch (MalformedJsonException expected) { } 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")); strategy.readNumber(fromString("1e400"));
fail(); fail();
} catch (MalformedJsonException expected) { } 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.NaN, strategy.readNumber(fromStringLenient("NaN")));
assertEquals(Double.POSITIVE_INFINITY, strategy.readNumber(fromStringLenient("Infinity"))); assertEquals(Double.POSITIVE_INFINITY, strategy.readNumber(fromStringLenient("Infinity")));
assertEquals(Double.NEGATIVE_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")); strategy.readNumber(fromString("NaN"));
fail(); fail();
} catch (MalformedJsonException expected) { } catch (MalformedJsonException expected) {
assertEquals("Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 1 path $", expected.getMessage());
} }
try { try {
strategy.readNumber(fromString("Infinity")); strategy.readNumber(fromString("Infinity"));
fail(); fail();
} catch (MalformedJsonException expected) { } catch (MalformedJsonException expected) {
assertEquals("Use JsonReader.setLenient(true) to accept malformed JSON at line 1 column 1 path $", expected.getMessage());
} }
try { try {
strategy.readNumber(fromString("-Infinity")); strategy.readNumber(fromString("-Infinity"));
fail(); fail();
} catch (MalformedJsonException expected) { } 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("10.1"), strategy.readNumber(fromString("10.1")));
assertEquals(new BigDecimal("3.141592653589793238462643383279"), strategy.readNumber(fromString("3.141592653589793238462643383279"))); assertEquals(new BigDecimal("3.141592653589793238462643383279"), strategy.readNumber(fromString("3.141592653589793238462643383279")));
assertEquals(new BigDecimal("1e400"), strategy.readNumber(fromString("1e400"))); 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 { public void testNullsAreNeverExpected() throws IOException {