json
json copied to clipboard
BigDecimal::INFINITY and BigDecimal::NAN to_json and as_json should error out similar to Float::INFINITY and Float::NAN
Currently, Float::INFINITY and Float::NAN error out when we try to convert them into JSON representation using as_json or to_json based on the following code from /ruby/ext/json/generator.c
if (!allow_nan) {
if (isinf(value)) {
fbuffer_free(buffer);
rb_raise(eGeneratorError, "%u: %"PRIsVALUE" not allowed in JSON", __LINE__, RB_OBJ_STRING(tmp));
} else if (isnan(value)) {
fbuffer_free(buffer);
rb_raise(eGeneratorError, "%u: %"PRIsVALUE" not allowed in JSON", __LINE__, RB_OBJ_STRING(tmp));
}
}
Should same treatment be applied to BigDecimal::INFINITY and BigDecimal::NAN?
Here is the RFC link which says that
Numeric values that cannot be represented as sequences of digits such as Infinity and NaN) are not permitted
https://www.ietf.org/rfc/rfc4627.txt
Also related question: What is the purpose of this file - https://github.com/flori/json/blob/master/lib/json/add/bigdecimal.rb I see it was added for BigDecimal compatability but it is not used in Ruby for BigDecimal#to_json. The to_json call currently goes through Object#to_json.
Sorry for the late reply.
Float
values are generated as JSON litterals. NaN
and INFINITY
will either error, or if allow_nan: true
is passed will be generated as NaN
and INFINITY
(note: no quotes or anything, these are not JSON strings).
This are not valid JSON and browsers will generate a parse error.
BigDecimal
are generated very differently. First, you should require json/add/bigdecimal
(documentation was much improved recently). Second, these are additions, so they will be valid JSON, but to round trip you will need to use the (unsafe!) options create_additions: true
.
$ ruby -r json -r bigdecimal -r json/add/bigdecimal -e "puts JSON.generate([Float::INFINITY, BigDecimal::INFINITY], allow_nan: true)"
[Infinity,{"json_class":"BigDecimal","b":"9:Infinity"}]
$ ruby -r json -r bigdecimal -r json/add/bigdecimal -e 'p JSON.parse("[Infinity,{\"json_class\":\"BigDecimal\",\"b\":\"9:Infinity\"}]", allow_nan: true, create_additions: true)'
[Infinity, Infinity] # First is Float::INFINITY, second is BigDecimal::INFINITY
HTH
This issue can be closed.