data.json

Double "positive infinity" value leads to json strings that can not be decoded

Details

  • Type: Defect Defect
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Completed
  • Affects Version/s: None
  • Fix Version/s: None
  • Component/s: None
  • Labels:
    None
  • Environment:

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)

Activity

Hide
Stuart Sierra added a comment -

Released as part of version 0.2.5

Show
Stuart Sierra added a comment - Released as part of version 0.2.5
Hide
Anton Logvinenko added a comment -

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!

Show
Anton Logvinenko added a comment - 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!
Hide
Stuart Sierra added a comment -

Fixed on Git master branch as of b4ba1fc0.

Holding release 0.2.5 for possible feedback.

Show
Stuart Sierra added a comment - Fixed on Git master branch as of b4ba1fc0. Holding release 0.2.5 for possible feedback.
Hide
Anton Logvinenko added a comment -

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.

Show
Anton Logvinenko added a comment - 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.
Hide
Tim Clemons added a comment - - edited

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.

Show
Tim Clemons added a comment - - edited 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.

People

Vote (0)
Watch (1)

Dates

  • Created:
    Updated:
    Resolved: