-
Notifications
You must be signed in to change notification settings - Fork 4.4k
Fix #2817: Add precision check to JsonTreeReader.nextInt() and nextLong() #3029
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -108,7 +108,7 @@ public static JsonElement parseReader(Reader reader) throws JsonIOException, Jso | |
| try { | ||
| JsonReader jsonReader = new JsonReader(reader); | ||
| JsonElement element = parseReader(jsonReader); | ||
| if (!element.isJsonNull() && jsonReader.peek() != JsonToken.END_DOCUMENT) { | ||
| if (jsonReader.peek() != JsonToken.END_DOCUMENT) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This accidentally includes changes from your other PR? |
||
| throw new JsonSyntaxException("Did not consume the entire document."); | ||
| } | ||
| return element; | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -258,7 +258,29 @@ public long nextLong() throws IOException { | |||||
| throw new IllegalStateException( | ||||||
| "Expected " + JsonToken.NUMBER + " but was " + token + locationString()); | ||||||
| } | ||||||
| long result = ((JsonPrimitive) peekStack()).getAsLong(); | ||||||
| Object o = peekStack(); | ||||||
| long result; | ||||||
| if (o instanceof JsonPrimitive) { | ||||||
| JsonPrimitive primitive = (JsonPrimitive) o; | ||||||
| if (primitive.isNumber()) { | ||||||
| Number number = primitive.getAsNumber(); | ||||||
| if (number instanceof Long || number instanceof Integer) { | ||||||
| result = number.longValue(); | ||||||
| } else { | ||||||
|
Comment on lines
+267
to
+269
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This will probably need explicit handling for Maybe what you could do is:
This is just a suggestion though. Maybe there are other ways to solve this as well.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similarly, might also need special handling for Maybe public long longValueExact() {
try {
return Long.parseLong(value);
} catch (NumberFormatException ignored) {
BigDecimal bigDecimal = asBigDecimal();
try {
return bigDecimal.longValueExact();
} catch (ArithmeticException arithmeticException) {
NumberFormatException e = new NumberFormatException(arithmeticException.getMessage());
e.initCause(arithmeticException);
throw e;
}
}
}(but might have to catch the |
||||||
| // For other number types (e.g., Double, BigDecimal), check for loss of precision | ||||||
| double doubleValue = number.doubleValue(); | ||||||
| result = (long) doubleValue; | ||||||
| if (result != doubleValue) { | ||||||
| throw new NumberFormatException( | ||||||
| "Expected a long but was " + number + locationString()); | ||||||
| } | ||||||
| } | ||||||
| } else { | ||||||
| result = Long.parseLong(primitive.getAsString()); | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe this could instead still call
Suggested change
|
||||||
| } | ||||||
| } else { | ||||||
| throw new IllegalStateException("Unexpected token: " + o); | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Might be better to use
Suggested change
|
||||||
| } | ||||||
| popStack(); | ||||||
| if (stackSize > 0) { | ||||||
| pathIndices[stackSize - 1]++; | ||||||
|
|
@@ -273,7 +295,29 @@ public int nextInt() throws IOException { | |||||
| throw new IllegalStateException( | ||||||
| "Expected " + JsonToken.NUMBER + " but was " + token + locationString()); | ||||||
| } | ||||||
| int result = ((JsonPrimitive) peekStack()).getAsInt(); | ||||||
| Object o = peekStack(); | ||||||
| int result; | ||||||
| if (o instanceof JsonPrimitive) { | ||||||
| JsonPrimitive primitive = (JsonPrimitive) o; | ||||||
| if (primitive.isNumber()) { | ||||||
| Number number = primitive.getAsNumber(); | ||||||
| if (number instanceof Integer) { | ||||||
| result = number.intValue(); | ||||||
| } else { | ||||||
| // For other number types (e.g., Long, Double, BigDecimal), check for loss of precision | ||||||
| double doubleValue = number.doubleValue(); | ||||||
| result = (int) doubleValue; | ||||||
| if (result != doubleValue) { | ||||||
| throw new NumberFormatException( | ||||||
| "Expected an int but was " + number + locationString()); | ||||||
| } | ||||||
| } | ||||||
| } else { | ||||||
| result = Integer.parseInt(primitive.getAsString()); | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe this could instead still call
Suggested change
|
||||||
| } | ||||||
| } else { | ||||||
| throw new IllegalStateException("Unexpected token: " + o); | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Might be better to use
Suggested change
|
||||||
| } | ||||||
| popStack(); | ||||||
| if (stackSize > 0) { | ||||||
| pathIndices[stackSize - 1]++; | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This accidentally includes changes from your other PR?