diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2020-09-23 21:30:30 -0700 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2020-09-30 02:59:39 +0000 |
commit | 90168f3efb91f247d33726772665fc84bb3e9f30 (patch) | |
tree | c64727f818a4441f597aab4e08332d9562060d30 /src/corelib/serialization | |
parent | 9d59f812a32f14aa0e0d452cdfe3e7c09d19dde8 (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.cpp | 40 |
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()), |