Infinity and JSON

Originally posted on the Agworld Developers Blog, hosted on Tumblr, on September 12, 2012.

Jason Hutchens
The Magic Pantry
2 min readJun 13, 2022

--

It seems that many JSON parsers/generators aren’t idempotent when it comes to Infinity.

We had a problem recently where a floating point result from a .NET server was returned in a JSON string like this:

{"name": Infinity}

That ain’t valid JSON, according to RFC 4627. Here’s what happened when we try to parse it in Ruby:

>> require 'json'
=> true
>> result = '{"name": Infinity}'
=> "{\"name\": Infinity}"
>> JSON.parse(result)
JSON::ParserError: 216: unexpected token at ' Infinity}'

Luckily, we can work-around this problem as follows:

>> result.gsub!(/Infinity/, '1e1000')
=> "{\"name\": 1e1000}"
>> data = JSON.parse(result)
=> {"name"=>Infinity}

Great! So now we can do manipulations on the Ruby hash. But, later, if we render that Hash as JSON, then we’ll get problems.

>> data.to_json
JSON::GeneratorError: 775: Infinity not allowed in JSON

What happens on the JavaScript side? Much the same thing, it turns out:

> result = '{"name": Infinity}'
"{"name": Infinity}"
> JSON.parse(result)
SyntaxError: Unexpected token I

Even better, the solution is exactly the same:

> result = result.replace(/Infinity/g,"1e1000")
"{"name": 1e1000}"
> data = JSON.parse(result)
v Object
result: Infinity
> __proto__: Object

JavaScript does comply with RFC 4627, however, unlike the JSON libraries that we use in Ruby (and presumably unlike whatever the .NET service was doing):

> JSON.stringify(data)
"{"name":null}"

But the best solution, I think, would be to use the ‘1e1000’ hack to preserve the value of ‘Infinity’ from end-to-end.

This article was originally posted on the Agworld Developers Blog, hosted on Tumblr, on September 21, 2012, and is almost certainly out of date by now.

--

--