Module: wine Branch: master Commit: 9b52a967b7bb1ef7c6fd404f1239e1d1c1648ee5 URL: https://source.winehq.org/git/wine.git/?a=commit;h=9b52a967b7bb1ef7c6fd404f1... Author: Piotr Caban <piotr(a)codeweavers.com> Date: Tue Mar 26 10:26:36 2019 +0100 ntdll: Fix _strnicmp implementation to not depend on locale. Signed-off-by: Piotr Caban <piotr(a)codeweavers.com> Signed-off-by: Alexandre Julliard <julliard(a)winehq.org> --- dlls/ntdll/string.c | 29 ++++++++++++++++++++++------- dlls/ntdll/tests/string.c | 26 ++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 7 deletions(-) diff --git a/dlls/ntdll/string.c b/dlls/ntdll/string.c index efae4d4..853bed6 100644 --- a/dlls/ntdll/string.c +++ b/dlls/ntdll/string.c @@ -258,21 +258,36 @@ INT __cdecl _memicmp( LPCSTR s1, LPCSTR s2, DWORD len ) /********************************************************************* - * _stricmp (NTDLL.@) - * _strcmpi (NTDLL.@) + * _strnicmp (NTDLL.@) */ -int __cdecl _stricmp( LPCSTR str1, LPCSTR str2 ) +int __cdecl _strnicmp( LPCSTR str1, LPCSTR str2, size_t n ) { - return strcasecmp( str1, str2 ); + int l1, l2; + + while (n--) + { + l1 = (unsigned char)NTDLL_tolower(*str1); + l2 = (unsigned char)NTDLL_tolower(*str2); + if (l1 != l2) + { + if (sizeof(void *) > sizeof(int)) return l1 - l2; + return l1 - l2 > 0 ? 1 : -1; + } + if (!l1) return 0; + str1++; + str2++; + } + return 0; } /********************************************************************* - * _strnicmp (NTDLL.@) + * _stricmp (NTDLL.@) + * _strcmpi (NTDLL.@) */ -int __cdecl _strnicmp( LPCSTR str1, LPCSTR str2, size_t n ) +int __cdecl _stricmp( LPCSTR str1, LPCSTR str2 ) { - return strncasecmp( str1, str2, n ); + return _strnicmp( str1, str2, -1 ); } diff --git a/dlls/ntdll/tests/string.c b/dlls/ntdll/tests/string.c index 22f2359..7954508 100644 --- a/dlls/ntdll/tests/string.c +++ b/dlls/ntdll/tests/string.c @@ -64,6 +64,7 @@ static int (WINAPIV *p__snprintf)(char *, size_t, const char *, ...); static int (__cdecl *p_tolower)(int); static int (__cdecl *p_toupper)(int); +static int (__cdecl *p__strnicmp)(LPCSTR,LPCSTR,size_t); static void InitFunctionPtrs(void) { @@ -105,6 +106,7 @@ static void InitFunctionPtrs(void) p_tolower = (void *)GetProcAddress(hntdll, "tolower"); p_toupper = (void *)GetProcAddress(hntdll, "toupper"); + p__strnicmp = (void *)GetProcAddress(hntdll, "_strnicmp"); } /* if */ } @@ -1381,6 +1383,29 @@ static void test_toupper(void) } } +static void test__strnicmp(void) +{ + BOOL is_win64 = (sizeof(void *) > sizeof(int)); + int ret; + + ok(p__strnicmp != NULL, "_strnicmp is not available\n"); + + ret = p__strnicmp("a", "C", 1); + ok(ret == (is_win64 ? -2 : -1), "_strnicmp returned %d\n", ret); + ret = p__strnicmp("a", "c", 1); + ok(ret == (is_win64 ? -2 : -1), "_strnicmp returned %d\n", ret); + ret = p__strnicmp("C", "a", 1); + ok(ret == (is_win64 ? 2 : 1), "_strnicmp returned %d\n", ret); + ret = p__strnicmp("c", "a", 1); + ok(ret == (is_win64 ? 2 : 1), "_strnicmp returned %d\n", ret); + ret = p__strnicmp("ijk0", "IJK1", 3); + ok(!ret, "_strnicmp returned %d\n", ret); + ret = p__strnicmp("ijk0", "IJK1", 4); + ok(ret == -1, "_strnicmp returned %d\n", ret); + ret = p__strnicmp("ijk\0X", "IJK\0Y", 5); + ok(!ret, "_strnicmp returned %d\n", ret); +} + START_TEST(string) { InitFunctionPtrs(); @@ -1419,4 +1444,5 @@ START_TEST(string) test__snprintf(); test_tolower(); test_toupper(); + test__strnicmp(); }