summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2018-06-25 15:45:32 +0200
committerSimon Hausmann <simon.hausmann@qt.io>2018-06-27 16:21:22 +0000
commitcd64a96b31f57e522ab8d29c8357acf384012ebe (patch)
treeba7b04f22537bad4784ee65c386705ea3794feec /src/corelib
parent00d9ade6e62b81294d6a306632edae791e7b5fec (diff)
Fix QString::localeAwareCompare with composed/decomposed strings on Windows
With ICU and on macOS it appears that the comparison is done on a canonical form, while CompareString(Ex) does not do that, as the added test verifies. Explicit normalization fixes that. As a bonus, this also unifies the code path between regular Windows and UWP by unconditionally using CompareStringEx (which requires Vista or later). This issue surfaced while running the ECMASCript 6 Conformance Test Suite in QtQml. This re-uses the existing test for localeAwareCompare, which was disabled on Windows, macOS and Linux with ICU (the common case). Change-Id: I52440fce60b54745ead1eff005ec51e98e2a79ec Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com>
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/tools/qstring.cpp9
1 files changed, 4 insertions, 5 deletions
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index c2e62a47f7..b6731cffcd 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -6393,11 +6393,10 @@ int QString::localeAwareCompare_helper(const QChar *data1, int length1,
Qt::CaseSensitive);
#if defined(Q_OS_WIN)
-# ifndef Q_OS_WINRT
- int res = CompareString(GetUserDefaultLCID(), 0, (wchar_t*)data1, length1, (wchar_t*)data2, length2);
-# else
- int res = CompareStringEx(LOCALE_NAME_USER_DEFAULT, 0, (LPCWSTR)data1, length1, (LPCWSTR)data2, length2, NULL, NULL, 0);
-# endif
+ QString lhs = QString::fromRawData(data1, length1).normalized(QString::NormalizationForm_C);
+ QString rhs = QString::fromRawData(data2, length2).normalized(QString::NormalizationForm_C);
+
+ int res = CompareStringEx(LOCALE_NAME_USER_DEFAULT, 0, (LPWSTR)lhs.constData(), lhs.length(), (LPWSTR)rhs.constData(), rhs.length(), NULL, NULL, 0);
switch (res) {
case CSTR_LESS_THAN: