summaryrefslogtreecommitdiffstats
path: root/src/corelib/serialization
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2020-09-23 21:30:30 -0700
committerThiago Macieira <thiago.macieira@intel.com>2020-09-29 16:14:37 -0700
commitf00d322f6701580f97f38794b83b0ec13973d177 (patch)
tree6ec601b266eb936d9420ef4075f7611cfe390529 /src/corelib/serialization
parent66c8fc4831a58cd34ea4a410b5191b44388613f2 (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 Pick-to: 5.15 Change-Id: I0d3ff441bec041728945fffd16379dec418637ca Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
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 116e7f6995..525cbfb3a0 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()),