From bda2e3d16af776e0f607d56bbab6eac22f8f2d58 Mon Sep 17 00:00:00 2001 From: Marcono1234 Date: Tue, 12 Oct 2021 01:14:47 +0200 Subject: [PATCH] Improve number strategy implementation (#1987) * Fix GsonBuilder not copying number strategies from Gson * Improve ToNumberPolicy exception messages --- .../java/com/google/gson/GsonBuilder.java | 2 ++ .../java/com/google/gson/ToNumberPolicy.java | 6 ++--- .../gson/internal/bind/JsonTreeReader.java | 2 +- .../com/google/gson/ToNumberPolicyTest.java | 24 +++++++++++++++++++ 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/gson/src/main/java/com/google/gson/GsonBuilder.java b/gson/src/main/java/com/google/gson/GsonBuilder.java index 1874e7de9b..b798604ab6 100644 --- a/gson/src/main/java/com/google/gson/GsonBuilder.java +++ b/gson/src/main/java/com/google/gson/GsonBuilder.java @@ -130,6 +130,8 @@ public GsonBuilder() { this.timeStyle = gson.timeStyle; this.factories.addAll(gson.builderFactories); this.hierarchyFactories.addAll(gson.builderHierarchyFactories); + this.objectToNumberStrategy = gson.objectToNumberStrategy; + this.numberToNumberStrategy = gson.numberToNumberStrategy; } /** diff --git a/gson/src/main/java/com/google/gson/ToNumberPolicy.java b/gson/src/main/java/com/google/gson/ToNumberPolicy.java index 1c6f349dc5..e7f91c9300 100644 --- a/gson/src/main/java/com/google/gson/ToNumberPolicy.java +++ b/gson/src/main/java/com/google/gson/ToNumberPolicy.java @@ -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); } } } diff --git a/gson/src/main/java/com/google/gson/internal/bind/JsonTreeReader.java b/gson/src/main/java/com/google/gson/internal/bind/JsonTreeReader.java index 60f4296bb0..ac6593350e 100644 --- a/gson/src/main/java/com/google/gson/internal/bind/JsonTreeReader.java +++ b/gson/src/main/java/com/google/gson/internal/bind/JsonTreeReader.java @@ -283,7 +283,7 @@ JsonElement nextJsonElement() throws IOException { } @Override public String toString() { - return getClass().getSimpleName(); + return getClass().getSimpleName() + locationString(); } public void promoteNameToValue() throws IOException { diff --git a/gson/src/test/java/com/google/gson/ToNumberPolicyTest.java b/gson/src/test/java/com/google/gson/ToNumberPolicyTest.java index d4f77f2905..db9898d47d 100644 --- a/gson/src/test/java/com/google/gson/ToNumberPolicyTest.java +++ b/gson/src/test/java/com/google/gson/ToNumberPolicyTest.java @@ -33,6 +33,12 @@ public void testDouble() throws IOException { 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 void testLongOrDouble() throws IOException { 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 void testLongOrDouble() throws IOException { 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 void testBigDecimal() throws IOException { 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 {