summaryrefslogtreecommitdiffstats
path: root/src/corelib/serialization
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2020-09-23 21:30:30 -0700
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2020-09-30 02:59:39 +0000
commit90168f3efb91f247d33726772665fc84bb3e9f30 (patch)
treec64727f818a4441f597aab4e08332d9562060d30 /src/corelib/serialization
parent9d59f812a32f14aa0e0d452cdfe3e7c09d19dde8 (diff)
QJsonObject: fix sorting after parsing from JSON text
The logic was complex and missed the UTF-8 UTF-8 case. It ended up calling the UTF-8 to Latin1, resulting in an improperly-sorted container, which in turn meant keys were not found when searched. Fixes: QTBUG-86873 Change-Id: I0d3ff441bec041728945fffd16379dec418637ca Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> (cherry picked from commit f00d322f6701580f97f38794b83b0ec13973d177) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'src/corelib/serialization')
-rw-r--r--src/corelib/serialization/qjsonparser.cpp40
1 files changed, 11 insertions, 29 deletions
diff --git a/src/corelib/serialization/qjsonparser.cpp b/src/corelib/serialization/qjsonparser.cpp
index 6d0a92e094..17e6f111ab 100644
--- a/src/corelib/serialization/qjsonparser.cpp
+++ b/src/corelib/serialization/qjsonparser.cpp
@@ -379,8 +379,6 @@ error:
return QCborValue();
}
-
-
static void sortContainer(QCborContainerPrivate *container)
{
using Forward = QJsonPrivate::KeyIterator;
@@ -403,39 +401,23 @@ static void sortContainer(QCborContainerPrivate *container)
if (!bData)
return 1;
- // If StringIsAscii is set, we can use either the UTF-8 or the latin1 comparison
- // for the string as ASCII is a subset of both. If nothing is set, that means UTF-8.
-
- // We are currently missing an efficient comparison between UTF-8 and UTF-16 strings.
- // Therefore, we need to convert the UTF-8 string if we encounter such a case.
-
- if (aKey.flags & QtCbor::Element::StringIsAscii) {
- if (bKey.flags & QtCbor::Element::StringIsAscii)
- return QtPrivate::compareStrings(aData->asLatin1(), bData->asLatin1());
- if (bKey.flags & QtCbor::Element::StringIsUtf16)
- return QtPrivate::compareStrings(aData->asLatin1(), bData->asStringView());
-
- return QCborContainerPrivate::compareUtf8(aData, bData->asLatin1());
- }
+ // US-ASCII (StringIsAscii flag) is just a special case of UTF-8
+ // string, so we can safely ignore the flag.
if (aKey.flags & QtCbor::Element::StringIsUtf16) {
- if (bKey.flags & QtCbor::Element::StringIsAscii)
- return QtPrivate::compareStrings(aData->asStringView(), bData->asLatin1());
if (bKey.flags & QtCbor::Element::StringIsUtf16)
return QtPrivate::compareStrings(aData->asStringView(), bData->asStringView());
- // Nasty case. a is UTF-16 and b is UTF-8
- return QtPrivate::compareStrings(aData->asStringView(), bData->toUtf8String());
- }
-
- if (bKey.flags & QtCbor::Element::StringIsAscii)
- return QCborContainerPrivate::compareUtf8(aData, bData->asLatin1());
-
- // Nasty case. a is UTF-8 and b is UTF-16
- if (bKey.flags & QtCbor::Element::StringIsUtf16)
- return QtPrivate::compareStrings(aData->toUtf8String(), bData->asStringView());
+ return -QCborContainerPrivate::compareUtf8(bData, aData->asStringView());
+ } else {
+ if (bKey.flags & QtCbor::Element::StringIsUtf16)
+ return QCborContainerPrivate::compareUtf8(aData, bData->asStringView());
- return QCborContainerPrivate::compareUtf8(aData, bData->asLatin1());
+ // We're missing an explicit UTF-8 to UTF-8 comparison in Qt, but
+ // UTF-8 to UTF-8 comparison retains simple byte ordering, so we'll
+ // abuse the Latin-1 comparison function.
+ return QtPrivate::compareStrings(aData->asLatin1(), bData->asLatin1());
+ }
};
std::sort(Forward(container->elements.begin()), Forward(container->elements.end()),