AiorosXu / google-gson

Automatically exported from code.google.com/p/google-gson
0 stars 0 forks source link

Exception when deserializing Double.NaN, Double.NEGATIVE_INFINITY and Double.POSITIVE_INFINITY #81

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?

public class GsonDouble
{
    private double negInf = Double.NEGATIVE_INFINITY;
    private double posInf = Double.POSITIVE_INFINITY;
    private double notANumber = Double.NaN;
    private double number = 2.0;

    public static void main(String[] args)
    {
        Gson gson = new Gson();

        String json = gson.toJson(new GsonDouble());
        System.out.println(json);

        GsonDouble gsonDouble = gson.fromJson(json, GsonDouble.class);

    }
}

Exception in thread "main" com.google.gson.JsonParseException: Failed
parsing JSON source: java.io.StringReader@134bed0 to Json
    at com.google.gson.Gson.fromJson(Gson.java:376)
    at com.google.gson.Gson.fromJson(Gson.java:321)
    at com.google.gson.Gson.fromJson(Gson.java:297)
    at GsonDouble.main(GsonDouble.java:29)
Caused by: com.google.gson.TokenMgrError: Lexical error at line 1, column
12.  Encountered: "I" (73), after : ""
    at
com.google.gson.JsonParserTokenManager.getNextToken(JsonParserTokenManager.java:
999)
    at com.google.gson.JsonParser.jj_consume_token(JsonParser.java:366)
    at com.google.gson.JsonParser.Digits(JsonParser.java:267)
    at com.google.gson.JsonParser.JsonInt(JsonParser.java:241)
    at com.google.gson.JsonParser.JsonNumber(JsonParser.java:192)
    at com.google.gson.JsonParser.JsonValue(JsonParser.java:131)
    at com.google.gson.JsonParser.Pair(JsonParser.java:78)
    at com.google.gson.JsonParser.Members(JsonParser.java:61)
    at com.google.gson.JsonParser.JsonObject(JsonParser.java:42)
    at com.google.gson.JsonParser.parse(JsonParser.java:11)
    at com.google.gson.Gson.fromJson(Gson.java:370)
    ... 3 more

The serialized String looks as follows:

{"negInf":-Infinity,"posInf":Infinity,"notANumber":NaN,"number":2.0}

I guess the serialization is ok, since JavaScript uses Number.NaN,
Number.NEGATIVE_INFINITY and Number.POSITIVE_INFINITY and the text
representation fits the above JSON string.
The deserializer seems to be unaware of this.

I would be great if you could fix this for the upcoming release.

Original issue reported on code.google.com by nit...@googlemail.com on 12 Dec 2008 at 1:09

GoogleCodeExporter commented 9 years ago
As per the JSON spec, see http://tools.ietf.org/id/draft-crockford-jsonorg-json-
04.txt, infinity is not a valid JSON number. However, we will consider 
accepting it 
as valid input to our parser. BTW, this also means that we are generating 
invalid 
JSON when infinity is present. Any suggestions on a good approach to handle it? 
Should we just ignore the field, or should we throw an exception when a user 
tries to 
serialize infinity.

Original comment by inder123 on 18 Dec 2008 at 7:10

GoogleCodeExporter commented 9 years ago
r333 disallows NaN, positive or negative infinity double values to be 
serialized 
through Gson. We will add additional support for disallowing this through Float 
or 
BigDecimal. This is to ensure that we do not emit invalid JSON.

Original comment by inder123 on 18 Dec 2008 at 8:04

GoogleCodeExporter commented 9 years ago
The spec says "Numeric values that cannot be represented as sequences of digits 
(such
as Infinity and NaN) are not permitted." 
But the spec also says: 
"It is inappropriate to use Internet-Drafts as reference material or to cite 
them
other than as "work in progress.""
And: "Expires: June 10, 2006"

So maybe there is a new spec which allows NaN/Infinity and if not then one 
should
write one.

JavaScript has no problems with the above JSON-String as the example below 
shows:

<html>
<script>
var json =
"{\"negInf\":-Infinity,\"posInf\":Infinity,\"notANumber\":NaN,\"number\":2.0}";
var obj = eval('(' + json + ')');
alert("negInf= "+obj.negInf+" posInf= "+obj.posInf+" notANumber= 
"+obj.notANumber+"
number= "+obj.number);
alert("is NaN " + isNaN(obj.notANumber));
</script>
<body>
</body>
</html>

IMHO gson/json should support all values of the Double/Number object. The spec 
seems
to be outdated and incomplete.

Original comment by nit...@googlemail.com on 18 Dec 2008 at 8:42

GoogleCodeExporter commented 9 years ago
Quote from r333:
src + " is not a valid double value as per JavaScript specification."

I think this is definitely wrong since Number.NaN, Number.NEGATIVE_INFINITY and
Number.POSITIVE_INFINITY are perfectly legal within JavaScript. 

I guess, you mean JSON specification, but as I said before it is only a draft. 
You
should reconsider and support all Double values in GSON.

Original comment by nit...@googlemail.com on 18 Dec 2008 at 8:51

GoogleCodeExporter commented 9 years ago
You are right, these are valid JavaScript values. I looked up the spec for 
JavaScript 
http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf which 
defines these to be valid values in 4.3.20, 4.3.22, and 4.3.23.

However, the official spec for JSON http://www.ietf.org/rfc/rfc4627.txt 
explicitly 
marks these as non-permitted values. See section 2.4

Original comment by inder123 on 19 Dec 2008 at 9:45

GoogleCodeExporter commented 9 years ago
One approach that we can take is that we will accept these values but never 
output 
these values. This is to ensure that the JSON output by Gson complies with the 
spec.  
We can also provide a GsonBuilder setting to allow these values to be output. 
Will 
that be a good solution?

Original comment by inder123 on 19 Dec 2008 at 9:47

GoogleCodeExporter commented 9 years ago
r344 adds support for deserialization of NaN, Infinity and -Infinity

Original comment by inder123 on 19 Dec 2008 at 10:22

GoogleCodeExporter commented 9 years ago
r345 adds support for enabling serialization of NaN, Infinity and -Infinity

Original comment by inder123 on 20 Dec 2008 at 1:26

GoogleCodeExporter commented 9 years ago
Support for NaN should be there. I cannot unset a database column which is 
declared
as a number. ie. If a database column is declared as a number which can be null,
there is no way to unset this column once it is set from the UI; I'm using dojo 
with
Json and Gson.

Original comment by rakumar...@gmail.com on 28 Jan 2009 at 5:52

GoogleCodeExporter commented 9 years ago
Yes, we do have support for NaN in the latest beta release. Do you want us to 
do 
something different? 

Original comment by inder123 on 29 Jan 2009 at 2:21