Piotr Caban : ntdll: Fix _strnicmp implementation to not depend on locale.

Alexandre Julliard julliard at winehq.org
Tue Mar 26 16:43:14 CDT 2019


Module: wine
Branch: master
Commit: 9b52a967b7bb1ef7c6fd404f1239e1d1c1648ee5
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=9b52a967b7bb1ef7c6fd404f1239e1d1c1648ee5

Author: Piotr Caban <piotr at 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 at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at 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();
 }




More information about the wine-cvs mailing list