Module: wine Branch: master Commit: 4e2da207d70e5b052253311896a00f377a635804 URL: https://source.winehq.org/git/wine.git/?a=commit;h=4e2da207d70e5b05225331189...
Author: Alexandre Julliard julliard@winehq.org Date: Thu Jan 16 11:37:03 2020 +0100
msvcrt: Use unsigned comparisons in strcmp and strncmp.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48454 Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/msvcrt/string.c | 8 +++----- dlls/msvcrt/tests/string.c | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 5 deletions(-)
diff --git a/dlls/msvcrt/string.c b/dlls/msvcrt/string.c index c4bd8ab129..e091ef5f46 100644 --- a/dlls/msvcrt/string.c +++ b/dlls/msvcrt/string.c @@ -2289,8 +2289,8 @@ void* __cdecl MSVCRT_memchr(const void *ptr, int c, MSVCRT_size_t n) int __cdecl MSVCRT_strcmp(const char *str1, const char *str2) { while (*str1 && *str1 == *str2) { str1++; str2++; } - if (*str1 > *str2) return 1; - if (*str1 < *str2) return -1; + if ((unsigned char)*str1 > (unsigned char)*str2) return 1; + if ((unsigned char)*str1 < (unsigned char)*str2) return -1; return 0; }
@@ -2301,9 +2301,7 @@ int __cdecl MSVCRT_strncmp(const char *str1, const char *str2, MSVCRT_size_t len { if (!len) return 0; while (--len && *str1 && *str1 == *str2) { str1++; str2++; } - if (*str1 > *str2) return 1; - if (*str1 < *str2) return -1; - return 0; + return (unsigned char)*str1 - (unsigned char)*str2; }
/********************************************************************* diff --git a/dlls/msvcrt/tests/string.c b/dlls/msvcrt/tests/string.c index 08bc0781e1..440bed348a 100644 --- a/dlls/msvcrt/tests/string.c +++ b/dlls/msvcrt/tests/string.c @@ -57,6 +57,8 @@ static void* (__cdecl *pmemcpy)(void *, const void *, size_t n); static int (__cdecl *p_memcpy_s)(void *, size_t, const void *, size_t); static int (__cdecl *p_memmove_s)(void *, size_t, const void *, size_t); static int* (__cdecl *pmemcmp)(void *, const void *, size_t n); +static int (__cdecl *p_strcmp)(const char *, const char *); +static int (__cdecl *p_strncmp)(const char *, const char *, size_t); static int (__cdecl *p_strcpy)(char *dst, const char *src); static int (__cdecl *pstrcpy_s)(char *dst, size_t len, const char *src); static int (__cdecl *pstrcat_s)(char *dst, size_t len, const char *src); @@ -630,6 +632,37 @@ static void test_strdup(void) free( str ); }
+static void test_strcmp(void) +{ + int ret = p_strcmp( "abc", "abcd" ); + ok( ret == -1, "wrong ret %d\n", ret ); + ret = p_strcmp( "", "abc" ); + ok( ret == -1, "wrong ret %d\n", ret ); + ret = p_strcmp( "abc", "ab\xa0" ); + ok( ret == -1, "wrong ret %d\n", ret ); + ret = p_strcmp( "ab\xb0", "ab\xa0" ); + ok( ret == 1, "wrong ret %d\n", ret ); + ret = p_strcmp( "ab\xc2", "ab\xc2" ); + ok( ret == 0, "wrong ret %d\n", ret ); + + ret = p_strncmp( "abc", "abcd", 3 ); + ok( ret == 0, "wrong ret %d\n", ret ); + ret = p_strncmp( "", "abc", 3 ); + ok( ret == 0 - 'a', "wrong ret %d\n", ret ); + ret = p_strncmp( "abc", "ab\xa0", 4 ); + ok( ret == 'c' - 0xa0, "wrong ret %d\n", ret ); + ret = p_strncmp( "ab\xb0", "ab\xa0", 3 ); + ok( ret == 0xb0 - 0xa0, "wrong ret %d\n", ret ); + ret = p_strncmp( "ab\xb0", "ab\xa0", 2 ); + ok( ret == 0, "wrong ret %d\n", ret ); + ret = p_strncmp( "ab\xc2", "ab\xc2", 3 ); + ok( ret == 0, "wrong ret %d\n", ret ); + ret = p_strncmp( "abc", "abd", 0 ); + ok( ret == 0, "wrong ret %d\n", ret ); + ret = p_strncmp( "abc", "abc", 12 ); + ok( ret == 0, "wrong ret %d\n", ret ); +} + static void test_strcpy_s(void) { char dest[8]; @@ -4067,6 +4100,8 @@ START_TEST(string) SET(p_mbctype,"_mbctype"); SET(p__mb_cur_max,"__mb_cur_max"); SET(p_strcpy, "strcpy"); + SET(p_strcmp, "strcmp"); + SET(p_strncmp, "strncmp"); pstrcpy_s = (void *)GetProcAddress( hMsvcrt,"strcpy_s" ); pstrcat_s = (void *)GetProcAddress( hMsvcrt,"strcat_s" ); p_mbscat_s = (void*)GetProcAddress( hMsvcrt, "_mbscat_s" ); @@ -4134,6 +4169,7 @@ START_TEST(string) test_mbsspn(); test_mbsspnp(); test_strdup(); + test_strcmp(); test_strcpy_s(); test_memcpy_s(); test_memmove_s();