Skip to content

fix: JsonTreeReader nextInt/nextLong silently truncates fractional numbers - #3094

Open
Jerryyy985 wants to merge 1 commit into
google:mainfrom
Jerryyy985:fix-2817-tree-reader
Open

fix: JsonTreeReader nextInt/nextLong silently truncates fractional numbers#3094
Jerryyy985 wants to merge 1 commit into
google:mainfrom
Jerryyy985:fix-2817-tree-reader

Conversation

@Jerryyy985

Copy link
Copy Markdown

Summary

JsonTreeReader.nextInt()/nextLong() call Number.intValue()/longValue() directly, which silently truncates fractional values (42.12342), while the streaming JsonReader throws NumberFormatException for the same input. Behavior between the two readers is inconsistent.

Fix

Mirror JsonReader's precision check: for NUMBER tokens, reject values whose double representation is not exactly equal to the requested integer type (result != getAsDouble() guard, same as JsonReader.nextInt/long).

Verified against a 12-case boundary matrix (fractional / integral / overflow / NaN / BigInteger / BigDecimal paths) — TreeReader now matches JsonReader behavior with no regressions on valid inputs.

Fixes #2817

…mbers

JsonTreeReader.nextInt/nextLong call Number.intValue()/longValue() directly,
which silently truncates fractional values (42.123 -> 42), while the streaming
JsonReader throws NumberFormatException for the same input.

Fix: mirror JsonReader's precision check — reject NUMBER tokens whose double
value is not exactly representable as the requested integer type.

Fixes google#2817
@google-cla

google-cla Bot commented Aug 14, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@Marcono1234 Marcono1234 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks!

Could you please also add tests (probably in JsonTreeReaderTest)?
And do you think you will be able to sign the Contributor License Agreement?

result = primitive.getAsLong();
if (token == JsonToken.NUMBER && result != primitive.getAsDouble()) {
// Mirror JsonReader: reject numbers that cannot be exactly represented as a long
throw new NumberFormatException("Expected a long but was " + primitive.getAsString());

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Probably have to move this out of the try-catch(NumberFormatException), otherwise this exception is redundantly wrapped.

(same for nextInt below as well)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Inconsistency JsonReader vs JsonTreeReader about double precision loss

2 participants