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

Long upper limit value #1727

Open
lissxxxx opened this issue Jun 25, 2020 · 2 comments · May be fixed by #1737
Open

Long upper limit value #1727

lissxxxx opened this issue Jun 25, 2020 · 2 comments · May be fixed by #1737
Labels

Comments

@lissxxxx
Copy link

Use Gson

Gson gson = new Gson();
Long a = gson.fromJson("9223372036854775808", Long.class);
System.out.println(a);

=> 9223372036854775807

Use JsonPrimitive

var jp = new JsonPrimitive("9223372036854775808");
Long b = jp.getAsLong();
System.out.println(b);

=> java.lang.NumberFormatException: For input string: "9223372036854775808"

Use Long.valueOf

Long c = Long.valueOf("9223372036854775808");
System.out.println(c);

=> java.lang.NumberFormatException: For input string: "9223372036854775808"

Why is there no error in Gson?
Is this a bug? Or is it a specification?
I want an error to occur.

@lyubomyr-shaydariv
Copy link
Contributor

Most likely a bug. The built-in long/Long type adapter reads the token using nextLong() that is heavily overloaded under the hood and does more than just reading the token as a long integer value: it attempts to parse it as a double value, and then casts it to a long comparing both results (checking for the fraction). The value you provided cannot be checked here:

if (result != asDouble) { // Make sure no precision was lost casting to 'long'.

I want an error to occur.

As a workaround you might want to add the following custom long values type adapter to your GsonBuilder:

final class LongTypeAdapter extends TypeAdapter<Long> {

	private LongTypeAdapter() {}

	private static final TypeAdapter<Long> instance = new LongTypeAdapter().nullSafe();

	static TypeAdapter<Long> get() { return instance; }

	@Override public void write(final JsonWriter out, @Nonnull final Long value) throws IOException { out.value(value); }

	@Override @Nonnull public Long read(final JsonReader in) throws IOException { return Long.parseLong(in.nextString()); }

}

Not sure if this bug can be fixed not breaking the previous versions of Gson.

@Marcono1234
Copy link
Collaborator

Marcono1234 commented Jul 10, 2020

Fixing this would probably require writing an own Double.parseLong because comparing asDouble.toString() with peekedString could cause false positives, e.g.:

  • peekedString = "1e1"
  • asDouble.toString() = "10.0"

new BigDecimal(String) cannot be used for parsing either because it would break backward compatibility because it does not support hexadecimal values, e.g. 0xAp2 = 10 * 22 = 40 or the type prefix d/D.

Edit: Or the validation could only be added for integral values which match the pattern described by Long.parseLong. This would catch the case described by this issue, but would not cover some values accepted by Double.parseDouble.

yuedaxia76 pushed a commit to yuedaxia76/gson that referenced this issue Jul 16, 2020
@Marcono1234 Marcono1234 added the bug label Aug 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants