From 1df02b5f980b01a4e42f32061f1cba696b6a22e9 Mon Sep 17 00:00:00 2001 From: Sona Kurazyan Date: Fri, 7 Aug 2020 14:57:11 +0200 Subject: Fix conversions to JSON from QVariant After reimplementing Qt JSON support on top of CBOR, there were unintended behavior changes when converting QVariant{, List, Map} to QJson{Value, Array, List} due to reusing the code for converting QVariant* types to CBOR types, and from CBOR types to corresponding JSON types. In particular, conversions from QVariant containing QByteArray to JSON has been affected: according to RFC 7049, when converting from CBOR to JSON, raw byte array data must be encoded in base64url when converting to a JSON string. As a result QVariant* types containing QByteArray data ended up base64url-encoded when converted to JSON, instead of converting using QString::fromUtf8() as before. There were also differences when converting QRegularExpression. Reverted the behavior changes by adding a flag to internal methods for converting CBOR to JSON, to distinguish whether the conversion is done from QVariant* or CBOR types. These methods now will fall back to the old behavior, if the conversion is done using QJson*::fromVariant*(). Additionally fixed QJsonValue::fromVariant conversion for NaN and infinities: they should always convert to QJsonValue::Null. This works correctly when converting from variant to QJsonArray/QJsonObject, but has been wrong for QJsonValue. Added more tests to verify the expected behavior. [ChangeLog][Important Behavior Changes] Restored pre-5.15.0 behavior when converting from QVariant* to QJson* types. Unforeseen consequences of changes in 5.15.0 caused QByteArray data to be base64url-encoded; the handling of QRegularExpression was also unintentionally changed. These conversions are now reverted to the prior behavior. Additionally fixed QJsonValue::fromVariant conversions for NaN and infinities: they should always convert to QJsonValue::Null. Fixes: QTBUG-84739 Change-Id: Iaee667d00e5363906eedbb67948b7b39c9d0bc78 Reviewed-by: Thiago Macieira --- src/corelib/serialization/qjsonobject.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/corelib/serialization/qjsonobject.cpp') diff --git a/src/corelib/serialization/qjsonobject.cpp b/src/corelib/serialization/qjsonobject.cpp index beeb3b5a549..419021a7988 100644 --- a/src/corelib/serialization/qjsonobject.cpp +++ b/src/corelib/serialization/qjsonobject.cpp @@ -205,11 +205,14 @@ QJsonObject &QJsonObject::operator =(const QJsonObject &other) The keys in \a map will be used as the keys in the JSON object, and the QVariant values will be converted to JSON values. + \note Conversion from \l QVariant is not completely lossless. Please see + the documentation in QJsonValue::fromVariant() for more information. + \sa fromVariantHash(), toVariantMap(), QJsonValue::fromVariant() */ QJsonObject QJsonObject::fromVariantMap(const QVariantMap &map) { - return QCborMap::fromVariantMap(map).toJsonObject(); + return QJsonPrivate::Variant::toJsonObject(map); } /*! @@ -231,6 +234,9 @@ QVariantMap QJsonObject::toVariantMap() const The keys in \a hash will be used as the keys in the JSON object, and the QVariant values will be converted to JSON values. + \note Conversion from \l QVariant is not completely lossless. Please see + the documentation in QJsonValue::fromVariant() for more information. + \sa fromVariantMap(), toVariantHash(), QJsonValue::fromVariant() */ QJsonObject QJsonObject::fromVariantHash(const QVariantHash &hash) -- cgit v1.2.3