From 38550c562d918e783bb609622bc8fb46de1bfec4 Mon Sep 17 00:00:00 2001 From: Marius Kittler Date: Mon, 27 Feb 2017 22:16:41 +0100 Subject: [PATCH] json encoder: Harmonize number serialization with ES6 Ensures that numbers representable as 64-bit integer are not printed using exponent notation. Some JSON implementations such as the one of the Go standard library expect this in the default conversion to int. Change-Id: Ic3ac718b7fd36462b4fcabbfb100a528a87798c8 Reviewed-by: Thiago Macieira --- src/corelib/json/qjsonwriter.cpp | 9 +++++--- tests/auto/corelib/json/tst_qtjson.cpp | 29 ++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/src/corelib/json/qjsonwriter.cpp b/src/corelib/json/qjsonwriter.cpp index b1544c749de..12ce20ef09a 100644 --- a/src/corelib/json/qjsonwriter.cpp +++ b/src/corelib/json/qjsonwriter.cpp @@ -38,6 +38,7 @@ ** ****************************************************************************/ +#include #include #include "qjsonwriter_p.h" #include "qjson_p.h" @@ -129,10 +130,12 @@ static void valueToJson(const QJsonPrivate::Base *b, const QJsonPrivate::Value & break; case QJsonValue::Double: { const double d = v.toDouble(b); - if (qIsFinite(d)) // +2 to format to ensure the expected precision - json += QByteArray::number(d, 'g', QLocale::FloatingPointShortest); - else + if (qIsFinite(d)) { // +2 to format to ensure the expected precision + const double abs = std::abs(d); + json += QByteArray::number(d, abs == static_cast(abs) ? 'f' : 'g', QLocale::FloatingPointShortest); + } else { json += "null"; // +INF || -INF || NaN (see RFC4627#section2.4) + } break; } case QJsonValue::String: diff --git a/tests/auto/corelib/json/tst_qtjson.cpp b/tests/auto/corelib/json/tst_qtjson.cpp index 6aa5165e242..b215364f0e9 100644 --- a/tests/auto/corelib/json/tst_qtjson.cpp +++ b/tests/auto/corelib/json/tst_qtjson.cpp @@ -32,6 +32,7 @@ #include "qjsonobject.h" #include "qjsonvalue.h" #include "qjsondocument.h" +#include "qregularexpression.h" #include #define INVALID_UNICODE "\xCE\xBA\xE1" @@ -49,6 +50,7 @@ private Q_SLOTS: void testNumbers(); void testNumbers_2(); void testNumbers_3(); + void testNumbers_4(); void testObjectSimple(); void testObjectSmallKeys(); @@ -375,6 +377,33 @@ void tst_QtJson::testNumbers_3() QVERIFY(d1_1 != d2_1); } +void tst_QtJson::testNumbers_4() +{ + // no exponent notation used to print numbers between -2^64 and 2^64 + QJsonArray array; + array << QJsonValue(+1000000000000000.0); + array << QJsonValue(-1000000000000000.0); + array << QJsonValue(+9007199254740992.0); + array << QJsonValue(-9007199254740992.0); + array << QJsonValue(+9223372036854775808.0); + array << QJsonValue(-9223372036854775808.0); + array << QJsonValue(+18446744073709551616.0); + array << QJsonValue(-18446744073709551616.0); + const QByteArray json(QJsonDocument(array).toJson()); + const QByteArray expected = + "[\n" + " 1000000000000000,\n" + " -1000000000000000,\n" + " 9007199254740992,\n" + " -9007199254740992,\n" + " 9223372036854776000,\n" + " -9223372036854776000,\n" + " 18446744073709552000,\n" + " -18446744073709552000\n" + "]\n"; + QCOMPARE(json, expected); +} + void tst_QtJson::testObjectSimple() { QJsonObject object;