diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2020-09-23 21:30:30 -0700 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2020-09-29 16:14:37 -0700 |
commit | f00d322f6701580f97f38794b83b0ec13973d177 (patch) | |
tree | 6ec601b266eb936d9420ef4075f7611cfe390529 /src/corelib/serialization/qjsonparser.cpp | |
parent | 66c8fc4831a58cd34ea4a410b5191b44388613f2 (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/qjsonparser.cpp')
-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 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()), |