From: Bernhard Übelacker Subject: libwine: Do not compare strings "ab-c" and a-bc" as equal. Message-Id: <1472303988-10382-1-git-send-email-bernhardu@mailbox.org> Date: Sat, 27 Aug 2016 15:19:48 +0200 While working on bug #13340 I found that CompareString returns CSTR_EQUAL for "ISO8859-1" and "ISO-88591" while native does not. Windows 7 and up returns CSTR_LESS_THAN but versions below return CSTR_GREATER_THAN. Therefore added the "expected not" test. Signed-off-by: Bernhard Übelacker --- dlls/kernel32/tests/locale.c | 10 +++++++++- libs/wine/sortkey.c | 6 ++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/dlls/kernel32/tests/locale.c b/dlls/kernel32/tests/locale.c index 7cb7859..727cad5 100644 --- a/dlls/kernel32/tests/locale.c +++ b/dlls/kernel32/tests/locale.c @@ -1782,6 +1782,7 @@ struct comparestringa_entry { const char *second; int second_len; int ret; + int not_ret; }; static const struct comparestringa_entry comparestringa_data[] = { @@ -1829,6 +1830,10 @@ static const struct comparestringa_entry comparestringa_data[] = { { LOCALE_SYSTEM_DEFAULT, 0, "a", 2, "a\0x", 4, CSTR_LESS_THAN }, { LOCALE_SYSTEM_DEFAULT, 0, "a\0x", 4, "a", 1, CSTR_GREATER_THAN }, { LOCALE_SYSTEM_DEFAULT, 0, "a\0x", 4, "a", 2, CSTR_GREATER_THAN }, + { LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, "ab-c", -1, "a-bc", -1, 0, CSTR_EQUAL }, + { LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, "ab'c", -1, "a'bc", -1, 0, CSTR_EQUAL }, + { LOCALE_SYSTEM_DEFAULT, SORT_STRINGSORT, "ab-c", -1, "a-bc", -1, CSTR_GREATER_THAN }, + { LOCALE_SYSTEM_DEFAULT, SORT_STRINGSORT, "ab'c", -1, "a'bc", -1, CSTR_GREATER_THAN }, }; static void test_CompareStringA(void) @@ -1843,7 +1848,10 @@ static void test_CompareStringA(void) ret = CompareStringA(entry->lcid, entry->flags, entry->first, entry->first_len, entry->second, entry->second_len); - ok(ret == entry->ret, "%d: got %d, expected %d\n", i, ret, entry->ret); + ok(!entry->ret || ret == entry->ret, "%d: \"%s\" vs \"%s\": got %d, expected %d.\n", + i, entry->first, entry->second, ret, entry->ret); + ok(!entry->not_ret || ret != entry->not_ret, "%d: \"%s\" vs \"%s\": got %d, expected not %d.\n", + i, entry->first, entry->second, ret, entry->not_ret); } ret = CompareStringA(lcid, NORM_IGNORECASE, "Salut", -1, "Salute", -1); diff --git a/libs/wine/sortkey.c b/libs/wine/sortkey.c index 634e910..405e65f 100644 --- a/libs/wine/sortkey.c +++ b/libs/wine/sortkey.c @@ -158,6 +158,8 @@ static inline int compare_unicode_weights(int flags, const WCHAR *str1, int len1 { unsigned int ce1, ce2; int ret; + int first_hypen1 = -1; + int first_hypen2 = -1; /* 32-bit collation element table format: * unicode weight - high 16 bit, diacritic weight - high 8 bit of low 16 bit, @@ -193,6 +195,7 @@ static inline int compare_unicode_weights(int flags, const WCHAR *str1, int len1 { if (*str2 != '-' && *str2 != '\'') { + if (first_hypen1 == -1) first_hypen1 = len1; str1++; len1--; continue; @@ -200,6 +203,7 @@ static inline int compare_unicode_weights(int flags, const WCHAR *str1, int len1 } else if (*str2 == '-' || *str2 == '\'') { + if (first_hypen2 == -1) first_hypen2 = len2; str2++; len2--; continue; @@ -231,6 +235,8 @@ static inline int compare_unicode_weights(int flags, const WCHAR *str1, int len1 str2++; len2--; } + if (!(flags & SORT_STRINGSORT) && (len1 - len2) == 0 && first_hypen1 != -1 && first_hypen2 != -1) + return first_hypen1 - first_hypen2; return len1 - len2; } -- 2.1.4