-
Suggestion
-
Resolution: Invalid
-
P3: Somewhat important
-
None
-
6.8.3
-
None
RFC8259 section 6 (https://datatracker.ietf.org/doc/html/rfc8259#section-6) states that numbers in JSON consist of "an integer component that may be prefixed with an optional minus sign, which may be followed by a fraction part and/or an exponent part."
This means that given the following input:
{ "someInt": 5, "someDouble": 5.0, "otherDouble": 5.1 }"
a conforming parser should ensure that the "someInt" value only consists of an integer component, whereas the "someDouble" and "otherDouble" values have both an integer component plus a fractional component.
QJsonValue does not differentiate between the "someInt" and "someDouble" case properly - QJsonValue::isDouble() returns true for both values, but calling QJsonValue::toVariant() returns `QVariant(qlonglong, 5)` for both, even though QJsonValue::toVariant() correctly returns `QVariant(double, 5.1)` for the "otherDouble".
Clearly, QJsonValue::isDouble() should return false for "someInt", and true for "someDouble", and QJsonValue::toVariant() should return `QVariant(double, 5.0)` for "someDouble".
Repro:
#include <QCoreApplication> #include <QJsonDocument> #include <QJsonObject> #include <QJsonValue> #include <QVariant> #include <QString> #include <QtDebug> int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); QJsonDocument doc = QJsonDocument::fromJson( QByteArrayLiteral("{ \"someInt\": 5, \"someDouble\": 5.0, \"otherDouble\": 5.1 }")); QJsonObject obj = doc.object(); QJsonValue i = obj.value("someInt"); QJsonValue d = obj.value("someDouble"); QJsonValue f = obj.value("otherDouble"); qWarning() << "parse output:\n" << "i.type = " << i.type() << "," << "i.isDouble = " << i.isDouble() << "," << "i.toString = " << i.toString() << "," << "i.toVariant = " << i.toVariant() << ";\n" << "d.type = " << d.type() << "," << "d.isDouble = " << d.isDouble() << "," << "d.toString = " << d.toString() << "," << "d.toVariant = " << d.toVariant() << ";\n" << "f.type = " << f.type() << "," << "f.isDouble = " << f.isDouble() << "," << "f.toString = " << f.toString() << "," << "f.toVariant = " << f.toVariant() << ";\n"; return 0; }
Output:
parse output: i.type = 2 , i.isDouble = true , i.toString = "" , i.toVariant = QVariant(qlonglong, 5) ; d.type = 2 , d.isDouble = true , d.toString = "" , d.toVariant = QVariant(qlonglong, 5) ; f.type = 2 , f.isDouble = true , f.toString = "" , f.toVariant = QVariant(double, 5.1) ;
Expected output:
parse output: i.type = 6 , i.isDouble = false, i.toString = "" , i.toVariant = QVariant(qlonglong, 5) ; d.type = 2 , d.isDouble = true , d.toString = "" , d.toVariant = QVariant(double, 5) ; f.type = 2 , f.isDouble = true , f.toString = "" , f.toVariant = QVariant(double, 5.1) ;