<< Back to previous view

[DJSON-17] Double "positive infinity" value leads to json strings that can not be decoded Created: 21/May/14  Updated: 13/Jun/14  Resolved: 13/Jun/14

Status: Closed
Project: data.json
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Anton Logvinenko Assignee: Stuart Sierra
Resolution: Completed Votes: 0
Labels: None
Environment:

JSON library:
<dependency>
<groupId>org.clojure</groupId>
<artifactId>data.json</artifactId>
<version>0.2.4</version>
</dependency>

<dependency>
<groupId>org.clojure</groupId>
<artifactId>clojure</artifactId>
<version>1.4.0</version>
</dependency>



 Description   

If you put a Double/POSITIVE_INFINITY as a value somewhere in your Clojure-collection and convert it to JSON then it will become impossible to decode that JSON back to Clojure-collection. Double/POSITIVE_INFINITY is encoded as "Infinity" string. When you try to parse that JSON, you get an Exception "Exception JSON error (unexpected character): I clojure.data.json/-read".

Can't say whether this really is a bug, but the thing that looks bad is that I couldn't decode what I encoded with the same library, it's not always "x == (read-str (write-str x))".

Here is a simple test to reproduce this behaviour:

> (require '[clojure.data.json :as json])
nil
> (json/write-str Double/POSITIVE_INFINITY)
"Infinity"
> (json/read-str (json/write-str Double/POSITIVE_INFINITY))
Exception JSON error (unexpected character): I  clojure.data.json/-read (json.clj:226)

Originally I encountered this problem with clojure.data.json v. 0.1.2:

(json/read-json (json/json-str Double/POSITIVE_INFINITY))
Exception JSON error (unexpected character): I  clojure.data.json/read-json-reader (json.clj:158)


 Comments   
Comment by Tim Clemons [ 22/May/14 7:29 PM ]

JSON currently does not support any representation of infinity. In RFC4627, section 2.4 it reads:

Numeric values that cannot be represented as sequences of digits (such as Infinity and NaN) are not permitted.

A potential workaround would be to decide on a convention whereby :value-fn functions passed to write and read translate Infinity to and from a given String. However, that's an application specific solution that doesn't really belong in the library.

Comment by Anton Logvinenko [ 23/May/14 6:13 AM ]

Maybe json/write-str should just fail if the collection contains Nan or Infinity? Not sure if this will be the best behavior in all possible use cases, but it would be better in the application where I've encountered it. The server was processing messages from ActiveMQ and silently converting some Doubles to "Infinity" string. If it failed, the server would retry, then log the problem, put messages to DLQ queue and we would know about it. Instead the problem manifested itself only when someone requested the data, plus the stored data was already "corrupted" by the time.

Comment by Stuart Sierra [ 06/Jun/14 4:04 PM ]

Fixed on Git master branch as of b4ba1fc0.

Holding release 0.2.5 for possible feedback.

Comment by Anton Logvinenko [ 07/Jun/14 4:26 PM ]

I've installed local 0.2.5-SNAPSHOT and ran the code. Having NaN inside makes json/write throw an exception "Exception JSON error: cannot write Double NaN clojure.data.json/write-double (json.clj:368)" (similar for Infinity).

On the other hand, json/write with :value-fn works fine and I'm able to replace values I need to.

Seems to me everything works great!

Comment by Stuart Sierra [ 13/Jun/14 4:17 PM ]

Released as part of version 0.2.5

Generated at Wed Oct 22 05:09:03 CDT 2014 using JIRA 4.4#649-r158309.