From cd64a96b31f57e522ab8d29c8357acf384012ebe Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 25 Jun 2018 15:45:32 +0200 Subject: 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 Reviewed-by: Thiago Macieira Reviewed-by: Konstantin Ritt --- tests/auto/corelib/tools/qstring/tst_qstring.cpp | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'tests/auto/corelib/tools/qstring') diff --git a/tests/auto/corelib/tools/qstring/tst_qstring.cpp b/tests/auto/corelib/tools/qstring/tst_qstring.cpp index fefb533616..47ccfb8b8a 100644 --- a/tests/auto/corelib/tools/qstring/tst_qstring.cpp +++ b/tests/auto/corelib/tools/qstring/tst_qstring.cpp @@ -530,10 +530,8 @@ private slots: void integer_conversion(); void tortureSprintfDouble(); void toNum(); -#if !defined(Q_OS_WIN) void localeAwareCompare_data(); void localeAwareCompare(); -#endif void reverseIterators(); void split_data(); void split(); @@ -5487,8 +5485,6 @@ void tst_QString::tortureSprintfDouble() #include -#if !defined(Q_OS_WIN) -// On Q_OS_WIN, we cannot set the system or user locale void tst_QString::localeAwareCompare_data() { QTest::addColumn("locale"); @@ -5496,6 +5492,15 @@ void tst_QString::localeAwareCompare_data() QTest::addColumn("s2"); QTest::addColumn("result"); + // Compare decomposed and composed form + { + // From ES6 test262 test suite (built-ins/String/prototype/localeCompare/15.5.4.9_CE.js), addressing from Unicode 5.0, chapter 3.12. Boils + // down to this one-liner: console.log("\u1111\u1171\u11B6".localeCompare("\ud4db") + QTest::newRow("normalize") << QString() << QString::fromUtf8("\xED\x93\x9B") << QString::fromUtf8("\xE1\x84\x91\xE1\x85\xB1\xE1\x86\xB6") << 0; + } + +#if !defined(Q_OS_WIN) +// On Q_OS_WIN, we cannot set the system or user locale /* The C locale performs pure byte comparisons for Latin-1-specific characters (I think). Compare with Swedish @@ -5556,6 +5561,7 @@ void tst_QString::localeAwareCompare_data() QTest::newRow("german2") << QString("de_DE") << QString::fromLatin1("\xe4") << QString::fromLatin1("\xf6") << -1; QTest::newRow("german3") << QString("de_DE") << QString::fromLatin1("z") << QString::fromLatin1("\xf6") << 1; #endif +#endif //!defined(Q_OS_WIN) } void tst_QString::localeAwareCompare() @@ -5568,17 +5574,17 @@ void tst_QString::localeAwareCompare() QStringRef r1(&s1, 0, s1.length()); QStringRef r2(&s2, 0, s2.length()); + if (!locale.isEmpty()) { #if defined (Q_OS_DARWIN) || defined(QT_USE_ICU) - QSKIP("Setting the locale is not supported on OS X or ICU (you can set the C locale, but that won't affect localeAwareCompare)"); + QSKIP("Setting the locale is not supported on OS X or ICU (you can set the C locale, but that won't affect localeAwareCompare)"); #else - if (!locale.isEmpty()) { const char *newLocale = setlocale(LC_ALL, locale.toLatin1()); if (!newLocale) { setlocale(LC_ALL, ""); QSKIP("Please install the proper locale on this machine to test properly"); } - } #endif + } #ifdef QT_USE_ICU // ### for c1, ICU disagrees with libc on how to compare @@ -5633,7 +5639,6 @@ void tst_QString::localeAwareCompare() if (!locale.isEmpty()) setlocale(LC_ALL, ""); } -#endif //!defined(Q_OS_WIN) void tst_QString::reverseIterators() { -- cgit v1.2.3