From d518a8be2c03676d2b0d5c56305610da8421b9fe Mon Sep 17 00:00:00 2001 From: Daniel Lehman Date: Mon, 13 Aug 2018 17:43:38 -0700 Subject: [PATCH v2 2/4] msvcrt: Don't read past end of string in _strncoll/_wcsncoll. Signed-off-by: Daniel Lehman --- dlls/msvcrt/string.c | 3 ++- dlls/msvcrt/tests/string.c | 33 +++++++++++++-------------------- dlls/msvcrt/wcs.c | 3 ++- include/wine/unicode.h | 7 +++++++ 4 files changed, 24 insertions(+), 22 deletions(-) diff --git a/dlls/msvcrt/string.c b/dlls/msvcrt/string.c index c8cd390688..90d359181d 100644 --- a/dlls/msvcrt/string.c +++ b/dlls/msvcrt/string.c @@ -666,7 +666,8 @@ int CDECL MSVCRT__strncoll_l( const char* str1, const char* str2, MSVCRT_size_t if(!locinfo->lc_handle[MSVCRT_LC_COLLATE]) return strncmp(str1, str2, count); - return CompareStringA(locinfo->lc_handle[MSVCRT_LC_COLLATE], 0, str1, count, str2, count)-CSTR_EQUAL; + return CompareStringA(locinfo->lc_handle[MSVCRT_LC_COLLATE], 0, + str1, strnlen(str1, count), str2, strnlen(str2, count))-CSTR_EQUAL; } /********************************************************************* diff --git a/dlls/msvcrt/tests/string.c b/dlls/msvcrt/tests/string.c index a48f1fcef1..1a271454db 100644 --- a/dlls/msvcrt/tests/string.c +++ b/dlls/msvcrt/tests/string.c @@ -3395,11 +3395,10 @@ static void test__tcsncoll(void) const char *str2; size_t count; int exp; - BOOL todo; }; static const struct test tests[] = { { "English", "ABCD", "ABCD", 4, 0 }, - { "English", "ABCD", "ABCD", 10, 0, TRUE }, + { "English", "ABCD", "ABCD", 10, 0 }, { "English", "ABC", "ABCD", 3, 0 }, { "English", "ABC", "ABCD", 4, -1 }, @@ -3446,15 +3445,12 @@ static void test__tcsncoll(void) strcpy(str2, tests[i].str2); ret = _strncoll(str1, str2, tests[i].count); - todo_wine_if(tests[i].todo) - { - if (!tests[i].exp) - ok(!ret, "expected 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); - else if (tests[i].exp < 0) - ok(ret < 0, "expected < 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); - else - ok(ret > 0, "expected > 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); - } + if (!tests[i].exp) + ok(!ret, "expected 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); + else if (tests[i].exp < 0) + ok(ret < 0, "expected < 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); + else + ok(ret > 0, "expected > 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); memset(str1W, 0xee, sizeof(str1W)); len = mbstowcs(str1W, str1, ARRAY_SIZE(str1W)); @@ -3465,15 +3461,12 @@ static void test__tcsncoll(void) str2W[len] = 0; ret = _wcsncoll(str1W, str2W, tests[i].count); - todo_wine_if(tests[i].todo) - { - if (!tests[i].exp) - ok(!ret, "expected 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); - else if (tests[i].exp < 0) - ok(ret < 0, "expected < 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); - else - ok(ret > 0, "expected > 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); - } + if (!tests[i].exp) + ok(!ret, "expected 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); + else if (tests[i].exp < 0) + ok(ret < 0, "expected < 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); + else + ok(ret > 0, "expected > 0, got %d for %s, %s, %d\n", ret, str1, str2, (int)tests[i].count); } } diff --git a/dlls/msvcrt/wcs.c b/dlls/msvcrt/wcs.c index ed73fc6163..6fca17ed47 100644 --- a/dlls/msvcrt/wcs.c +++ b/dlls/msvcrt/wcs.c @@ -335,7 +335,8 @@ int CDECL MSVCRT__wcsncoll_l(const MSVCRT_wchar_t* str1, const MSVCRT_wchar_t* s if(!locinfo->lc_handle[MSVCRT_LC_COLLATE]) return strncmpW(str1, str2, count); - return CompareStringW(locinfo->lc_handle[MSVCRT_LC_COLLATE], 0, str1, count, str2, count)-CSTR_EQUAL; + return CompareStringW(locinfo->lc_handle[MSVCRT_LC_COLLATE], 0, + str1, strnlenW(str1, count), str2, strnlenW(str2, count))-CSTR_EQUAL; } /********************************************************************* diff --git a/include/wine/unicode.h b/include/wine/unicode.h index 35c61666d2..53b7a81e6e 100644 --- a/include/wine/unicode.h +++ b/include/wine/unicode.h @@ -201,6 +201,13 @@ WINE_UNICODE_INLINE unsigned int strlenW( const WCHAR *str ) return s - str; } +WINE_UNICODE_INLINE unsigned int strnlenW( const WCHAR *str, int n ) +{ + const WCHAR *s = str; + while ((n-- > 0) && *s) s++; + return s - str; +} + WINE_UNICODE_INLINE WCHAR *strcpyW( WCHAR *dst, const WCHAR *src ) { WCHAR *p = dst; -- 2.17.0