Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve number strategy implementation #1987

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions gson/src/main/java/com/google/gson/GsonBuilder.java
Expand Up @@ -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;
}

/**
Expand Down
6 changes: 3 additions & 3 deletions gson/src/main/java/com/google/gson/ToNumberPolicy.java
Expand Up @@ -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());
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uses getPath() instead of (implicit) in.toString() because the line and column number included by toString() would point behind the value (since it has already been consumed).

}
return d;
} catch (NumberFormatException doubleE) {
throw new JsonParseException("Cannot parse " + value, doubleE);
throw new JsonParseException("Cannot parse " + value + "; at path " + in.getPath(), doubleE);
}
}
}
Expand All @@ -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);
}
}
}
Expand Down
Expand Up @@ -283,7 +283,7 @@ JsonElement nextJsonElement() throws IOException {
}

@Override public String toString() {
return getClass().getSimpleName();
return getClass().getSimpleName() + locationString();
}

public void promoteNameToValue() throws IOException {
Expand Down
24 changes: 24 additions & 0 deletions gson/src/test/java/com/google/gson/ToNumberPolicyTest.java
Expand Up @@ -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) {
}
}

Expand All @@ -52,24 +58,35 @@ 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")));
try {
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());
}
}

Expand All @@ -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 {
Expand Down