Commit e93c9aca authored by Kenton Varda's avatar Kenton Varda

Merge pull request #262 from kamalmarhubi/json-encode-nan-inf

JSON: encode NaNs and infinite floats as `null`
parents 0a35b416 359e65e4
......@@ -127,8 +127,8 @@ const char ALL_TYPES_JSON[] =
" \"uInt16List\": [33333, 44444],\n"
" \"uInt32List\": [3333333333],\n"
" \"uInt64List\": [\"11111111111111111111\"],\n"
" \"float32List\": [5555.5, inf, -inf, nan],\n"
" \"float64List\": [7777.75, inf, -inf, nan],\n"
" \"float32List\": [5555.5, null, null, null],\n"
" \"float64List\": [7777.75, null, null, null],\n"
" \"textList\": [\"plugh\", \"xyzzy\", \"thud\"],\n"
" \"dataList\": [[111, 111, 112, 115], [101, 120, 104, 97, 117, 115, 116, 101, 100], [114, 102, 99, 51, 48, 57, 50]],\n"
" \"structList\": [\n"
......
......@@ -237,9 +237,20 @@ void JsonCodec::encode(DynamicValue::Reader input, Type type, JsonValue::Builder
case schema::Type::UINT8:
case schema::Type::UINT16:
case schema::Type::UINT32:
output.setNumber(input.as<double>());
break;
case schema::Type::FLOAT32:
case schema::Type::FLOAT64:
output.setNumber(input.as<double>());
{
double value = input.as<double>();
if (kj::inf() == value || -kj::inf() == value || kj::isNaN(value)) {
// These values are not allowed in the JSON spec. Setting the field as null matches the
// behavior of JSON.stringify in Firefox and Chrome.
output.setNull();
} else {
output.setNumber(value);
}
}
break;
case schema::Type::INT64:
output.setString(kj::str(input.as<int64_t>()));
......
......@@ -49,6 +49,8 @@ class JsonCodec {
// fields are only encoded if they are non-null.
// - 64-bit integers are encoded as strings, since JSON "numbers" are double-precision floating
// points which cannot store a 64-bit integer without losing data.
// - NaNs and infinite floating point numbers are not allowed by the JSON spec, and so are encoded
// as null. This matches the behavior of `JSON.stringify` in at least Firefox and Chrome.
// - Data is encoded as an array of numbers in the range [0,255]. You probably want to register
// a handler that does something better, like maybe base64 encoding, but there are a zillion
// different ways people do this.
......
......@@ -594,6 +594,9 @@ float nan();
#error "Not sure how to support your compiler."
#endif
inline constexpr bool isNaN(float f) { return f != f; }
inline constexpr bool isNaN(double f) { return f != f; }
// =======================================================================================
// Useful fake containers
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment