summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2019-10-21 10:26:45 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2019-11-05 10:12:04 +0100
commitedec095cf80b62057116ce75c581b5ca5866bdcc (patch)
treea849983cff625c80f9386865988f32ad552837cd /tests/auto/corelib
parente99b0016e8b639e40d5330e0c3eaa199b48e34f4 (diff)
Fix 64-bit integer support in QtJSON
Fixes parsing writing and pass-through of integers with higher precision than double can handle. Note this adds extra precision compared to JavaScript, but the JSON files read and written this way are still valid, and the extra precision in reading and writing this way is used by many JSON libraries. Fixes: QTBUG-28560 Change-Id: I30b2415c928d1c34c8cb4e4c6218602095e7e8aa Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'tests/auto/corelib')
-rw-r--r--tests/auto/corelib/serialization/json/tst_qtjson.cpp78
-rw-r--r--tests/auto/corelib/serialization/qcborvalue_json/tst_qcborvalue_json.cpp15
2 files changed, 76 insertions, 17 deletions
diff --git a/tests/auto/corelib/serialization/json/tst_qtjson.cpp b/tests/auto/corelib/serialization/json/tst_qtjson.cpp
index 57aa67c142..50d3ab1f6b 100644
--- a/tests/auto/corelib/serialization/json/tst_qtjson.cpp
+++ b/tests/auto/corelib/serialization/json/tst_qtjson.cpp
@@ -52,6 +52,8 @@ private Q_SLOTS:
void testNumbers_3();
void testNumbers_4();
+ void testNumberComparisons();
+
void testObjectSimple();
void testObjectSmallKeys();
void testArraySimple();
@@ -218,26 +220,32 @@ void tst_QtJson::testNumbers()
{
int numbers[] = {
0,
- -1,
1,
+ 2,
+ -1,
+ -2,
+ (1<<25),
(1<<26),
(1<<27),
(1<<28),
+ -(1<<25),
-(1<<26),
-(1<<27),
-(1<<28),
(1<<26) - 1,
(1<<27) - 1,
(1<<28) - 1,
+ (1<<29) - 1,
-((1<<26) - 1),
-((1<<27) - 1),
- -((1<<28) - 1)
+ -((1<<28) - 1),
+ -((1<<29) - 1)
};
int n = sizeof(numbers)/sizeof(int);
QJsonArray array;
for (int i = 0; i < n; ++i)
- array.append((double)numbers[i]);
+ array.append(numbers[i]);
QByteArray serialized = QJsonDocument(array).toJson();
QJsonDocument json = QJsonDocument::fromJson(serialized);
@@ -246,8 +254,10 @@ void tst_QtJson::testNumbers()
QCOMPARE(array.size(), array2.size());
for (int i = 0; i < array.size(); ++i) {
QCOMPARE(array.at(i).type(), QJsonValue::Double);
+ QCOMPARE(array.at(i).toInt(), numbers[i]);
QCOMPARE(array.at(i).toDouble(), (double)numbers[i]);
QCOMPARE(array2.at(i).type(), QJsonValue::Double);
+ QCOMPARE(array2.at(i).toInt(), numbers[i]);
QCOMPARE(array2.at(i).toDouble(), (double)numbers[i]);
}
}
@@ -255,8 +265,10 @@ void tst_QtJson::testNumbers()
{
qint64 numbers[] = {
0,
- -1,
1,
+ 2,
+ -1,
+ -2,
(1ll<<54),
(1ll<<55),
(1ll<<56),
@@ -266,15 +278,21 @@ void tst_QtJson::testNumbers()
(1ll<<54) - 1,
(1ll<<55) - 1,
(1ll<<56) - 1,
+ (1ll<<57) - 1,
+ (1ll<<58) - 1,
+ (1ll<<59) + 1001,
-((1ll<<54) - 1),
-((1ll<<55) - 1),
- -((1ll<<56) - 1)
+ -((1ll<<56) - 1),
+ -((1ll<<57) - 1),
+ -((1ll<<58) - 1),
+ -((1ll<<59) + 1001),
};
int n = sizeof(numbers)/sizeof(qint64);
QJsonArray array;
for (int i = 0; i < n; ++i)
- array.append((double)numbers[i]);
+ array.append(QJsonValue(numbers[i]));
QByteArray serialized = QJsonDocument(array).toJson();
QJsonDocument json = QJsonDocument::fromJson(serialized);
@@ -283,8 +301,10 @@ void tst_QtJson::testNumbers()
QCOMPARE(array.size(), array2.size());
for (int i = 0; i < array.size(); ++i) {
QCOMPARE(array.at(i).type(), QJsonValue::Double);
+ QCOMPARE(array.at(i).toInteger(), numbers[i]);
QCOMPARE(array.at(i).toDouble(), (double)numbers[i]);
QCOMPARE(array2.at(i).type(), QJsonValue::Double);
+ QCOMPARE(array2.at(i).toInteger(), numbers[i]);
QCOMPARE(array2.at(i).toDouble(), (double)numbers[i]);
}
}
@@ -422,6 +442,46 @@ void tst_QtJson::testNumbers_4()
" -18446744073709552000\n"
"]\n";
QCOMPARE(json, expected);
+
+ QJsonArray array2;
+ array2 << QJsonValue(Q_INT64_C(+1000000000000000));
+ array2 << QJsonValue(Q_INT64_C(-1000000000000000));
+ array2 << QJsonValue(Q_INT64_C(+9007199254740992));
+ array2 << QJsonValue(Q_INT64_C(-9007199254740992));
+ array2 << QJsonValue(Q_INT64_C(+9223372036854775807));
+ array2 << QJsonValue(Q_INT64_C(-9223372036854775807));
+ const QByteArray json2(QJsonDocument(array2).toJson());
+ const QByteArray expected2 =
+ "[\n"
+ " 1000000000000000,\n"
+ " -1000000000000000,\n"
+ " 9007199254740992,\n"
+ " -9007199254740992,\n"
+ " 9223372036854775807,\n"
+ " -9223372036854775807\n"
+ "]\n";
+ QCOMPARE(json2, expected2);
+}
+
+void tst_QtJson::testNumberComparisons()
+{
+ // QJsonValues created using doubles only have double precision
+ QJsonValue llMinDbl(-9223372036854775807.0);
+ QJsonValue llMinPlus1Dbl(-9223372036854775806.0);
+ QCOMPARE(llMinDbl == llMinPlus1Dbl, -9223372036854775807.0 == -9223372036854775806.0); // true
+
+ // QJsonValues created using qint64 have full qint64 precision
+ QJsonValue llMin(Q_INT64_C(-9223372036854775807));
+ QJsonValue llMinPlus1(Q_INT64_C(-9223372036854775806));
+ QCOMPARE(llMin == llMinPlus1, Q_INT64_C(-9223372036854775807) == Q_INT64_C(-9223372036854775806)); // false
+
+ // The different storage formats should be able to compare as their C++ versions (all true)
+ QCOMPARE(llMin == llMinDbl, Q_INT64_C(-9223372036854775807) == -9223372036854775807.0);
+ QCOMPARE(llMinDbl == llMin, -9223372036854775807.0 == Q_INT64_C(-9223372036854775807));
+ QCOMPARE(llMinPlus1 == llMinPlus1Dbl, Q_INT64_C(-9223372036854775806) == -9223372036854775806.0);
+ QCOMPARE(llMinPlus1Dbl == llMinPlus1, -9223372036854775806.0 == Q_INT64_C(-9223372036854775806));
+ QCOMPARE(llMinPlus1 == llMinDbl, Q_INT64_C(-9223372036854775806) == -9223372036854775807.0);
+ QCOMPARE(llMinPlus1Dbl == llMin, -9223372036854775806.0 == Q_INT64_C(-9223372036854775807));
}
void tst_QtJson::testObjectSimple()
@@ -1160,8 +1220,8 @@ void tst_QtJson::fromVariant_data()
bool boolValue = true;
int intValue = -1;
uint uintValue = 1;
- long long longlongValue = -2;
- unsigned long long ulonglongValue = 2;
+ qlonglong longlongValue = -2;
+ qulonglong ulonglongValue = 2;
float floatValue = 3.3f;
double doubleValue = 4.4;
QString stringValue("str");
@@ -1207,7 +1267,7 @@ void tst_QtJson::fromVariant_data()
QTest::newRow("nullptr") << QVariant::fromValue(nullptr) << QJsonValue(QJsonValue::Null);
QTest::newRow("bool") << QVariant(boolValue) << QJsonValue(boolValue);
QTest::newRow("int") << QVariant(intValue) << QJsonValue(intValue);
- QTest::newRow("uint") << QVariant(uintValue) << QJsonValue(static_cast<double>(uintValue));
+ QTest::newRow("uint") << QVariant(uintValue) << QJsonValue(static_cast<qint64>(uintValue));
QTest::newRow("longlong") << QVariant(longlongValue) << QJsonValue(longlongValue);
QTest::newRow("ulonglong") << QVariant(ulonglongValue) << QJsonValue(static_cast<double>(ulonglongValue));
QTest::newRow("float") << QVariant(floatValue) << QJsonValue(floatValue);
diff --git a/tests/auto/corelib/serialization/qcborvalue_json/tst_qcborvalue_json.cpp b/tests/auto/corelib/serialization/qcborvalue_json/tst_qcborvalue_json.cpp
index 56245a7173..76f2bb924a 100644
--- a/tests/auto/corelib/serialization/qcborvalue_json/tst_qcborvalue_json.cpp
+++ b/tests/auto/corelib/serialization/qcborvalue_json/tst_qcborvalue_json.cpp
@@ -97,9 +97,12 @@ void tst_QCborValue_Json::toVariant_data()
add(1, 1, 1);
add(-1, -1, -1);
add(0., 0., 0.);
+ add(2., 2., 2.);
add(1.25, 1.25, 1.25);
add(-1.25, -1.25, -1.25);
add("Hello", "Hello", "Hello");
+ add(std::numeric_limits<qint64>::max(), std::numeric_limits<qint64>::max(), std::numeric_limits<qint64>::max());
+ add(std::numeric_limits<qint64>::min(), std::numeric_limits<qint64>::min(), std::numeric_limits<qint64>::min());
// converts to string in JSON:
add(QByteArray("Hello"), QByteArray("Hello"), "SGVsbG8");
@@ -123,14 +126,6 @@ void tst_QCborValue_Json::toVariant_data()
<< QVariant(qQNaN())
<< QJsonValue();
- // large integral values lose precision in JSON
- QTest::newRow("Integer:max") << QCborValue(std::numeric_limits<qint64>::max())
- << QVariant(std::numeric_limits<qint64>::max())
- << QJsonValue(std::numeric_limits<qint64>::max());
- QTest::newRow("Integer:min") << QCborValue(std::numeric_limits<qint64>::min())
- << QVariant(std::numeric_limits<qint64>::min())
- << QJsonValue(std::numeric_limits<qint64>::min());
-
// empty arrays and maps
add(QCborArray(), QVariantList(), QJsonArray());
add(QCborMap(), QVariantMap(), QJsonObject());
@@ -257,6 +252,10 @@ void tst_QCborValue_Json::fromJson_data()
QTest::newRow("0") << QCborValue(0) << QJsonValue(0.);
QTest::newRow("1") << QCborValue(1) << QJsonValue(1);
QTest::newRow("1.5") << QCborValue(1.5) << QJsonValue(1.5);
+ QTest::newRow("Integer:max") << QCborValue(std::numeric_limits<qint64>::max())
+ << QJsonValue(std::numeric_limits<qint64>::max());
+ QTest::newRow("Integer:min") << QCborValue(std::numeric_limits<qint64>::min())
+ << QJsonValue(std::numeric_limits<qint64>::min());
QTest::newRow("string") << QCborValue("Hello") << QJsonValue("Hello");
QTest::newRow("array") << QCborValue(QCborValue::Array) << QJsonValue(QJsonValue::Array);
QTest::newRow("map") << QCborValue(QCborValue::Map) << QJsonValue(QJsonValue::Object);