Module: wine Branch: master Commit: 4fa616c37cbaafdb4c9d973de81689c215601229 URL: http://source.winehq.org/git/wine.git/?a=commit;h=4fa616c37cbaafdb4c9d973de8...
Author: Bernhard Übelacker bernhardu@mailbox.org Date: Thu Aug 18 11:49:04 2016 +0200
msvcrt: Fix strtok_s and _mbstok_s for empty strings.
Signed-off-by: Bernhard Übelacker bernhardu@mailbox.org Signed-off-by: Piotr Caban piotr@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/msvcr90/tests/msvcr90.c | 88 ++++++++++++++++++++++++++++++++++++++++++++ dlls/msvcrt/mbcs.c | 3 ++ dlls/msvcrt/string.c | 3 ++ 3 files changed, 94 insertions(+)
diff --git a/dlls/msvcr90/tests/msvcr90.c b/dlls/msvcr90/tests/msvcr90.c index ecf25ec..a4bcdc5 100644 --- a/dlls/msvcr90/tests/msvcr90.c +++ b/dlls/msvcr90/tests/msvcr90.c @@ -92,8 +92,10 @@ static int* (__cdecl *p_errno)(void); static __msvcrt_ulong* (__cdecl *p_doserrno)(void); static void (__cdecl *p_srand)(unsigned int); static char* (__cdecl *p_strtok)(char*, const char*); +static char* (__cdecl *p_strtok_s)(char*, const char*, char**); static wchar_t* (__cdecl *p_wcstok)(wchar_t*, const wchar_t*); static unsigned char* (__cdecl *p__mbstok)(unsigned char*, const unsigned char*); +static unsigned char* (__cdecl *p__mbstok_s)(unsigned char*, const unsigned char*, unsigned char**); static char* (__cdecl *p_strerror)(int); static wchar_t* (__cdecl *p_wcserror)(int); static char* (__cdecl *p_tmpnam)(char*); @@ -355,8 +357,10 @@ static BOOL init(void) SET(p_doserrno, "__doserrno"); SET(p_srand, "srand"); SET(p_strtok, "strtok"); + SET(p_strtok_s, "strtok_s"); SET(p_wcstok, "wcstok"); SET(p__mbstok, "_mbstok"); + SET(p__mbstok_s, "_mbstok_s"); SET(p_strerror, "strerror"); SET(p_wcserror, "_wcserror"); SET(p_tmpnam, "tmpnam"); @@ -1547,6 +1551,88 @@ static void test_mbstowcs(void) p_setlocale(LC_ALL, "C"); }
+static void test_strtok_s(void) +{ + char test[] = "a/b"; + char empty[] = ""; + char space[] = " "; + char delim[] = "/"; + char *strret; + char *context; + + context = (char*)0xdeadbeef; + strret = p_strtok_s( test, delim, &context); + ok(strret == test, "Expected test, got %p.\n", strret); + ok(context == test+2, "Expected test+2, got %p.\n", context); + + strret = p_strtok_s( NULL, delim, &context); + ok(strret == test+2, "Expected test+2, got %p.\n", strret); + ok(context == test+3, "Expected test+3, got %p.\n", context); + + strret = p_strtok_s( NULL, delim, &context); + ok(strret == NULL, "Expected NULL, got %p.\n", strret); + ok(context == test+3, "Expected test+3, got %p.\n", context); + + context = NULL; + strret = p_strtok_s( empty, delim, &context); + ok(strret == NULL, "Expected NULL, got %p.\n", strret); + ok(context == empty, "Expected empty, got %p.\n", context); + + strret = p_strtok_s( NULL, delim, &context); + ok(strret == NULL, "Expected NULL, got %p.\n", strret); + ok(context == empty, "Expected empty, got %p.\n", context); + + context = NULL; + strret = p_strtok_s( space, delim, &context); + ok(strret == space, "Expected space, got %p.\n", strret); + ok(context == space+1, "Expected space+1, got %p.\n", context); + + strret = p_strtok_s( NULL, delim, &context); + ok(strret == NULL, "Expected NULL, got %p.\n", strret); + ok(context == space+1, "Expected space+1, got %p.\n", context); +} + +static void test__mbstok_s(void) +{ + unsigned char test[] = "a/b"; + unsigned char empty[] = ""; + unsigned char space[] = " "; + unsigned char delim[] = "/"; + unsigned char *strret; + unsigned char *context; + + context = (unsigned char*)0xdeadbeef; + strret = p__mbstok_s( test, delim, &context); + ok(strret == test, "Expected test, got %p.\n", strret); + ok(context == test+2, "Expected test+2, got %p.\n", context); + + strret = p__mbstok_s( NULL, delim, &context); + ok(strret == test+2, "Expected test+2, got %p.\n", strret); + ok(context == test+3, "Expected test+3, got %p.\n", context); + + strret = p__mbstok_s( NULL, delim, &context); + ok(strret == NULL, "Expected NULL, got %p.\n", strret); + ok(context == test+3, "Expected test+3, got %p.\n", context); + + context = NULL; + strret = p__mbstok_s( empty, delim, &context); + ok(strret == NULL, "Expected NULL, got %p.\n", strret); + ok(context == empty, "Expected empty, got %p.\n", context); + + strret = p__mbstok_s( NULL, delim, &context); + ok(strret == NULL, "Expected NULL, got %p.\n", strret); + ok(context == empty, "Expected empty, got %p.\n", context); + + context = NULL; + strret = p__mbstok_s( space, delim, &context); + ok(strret == space, "Expected space, got %p.\n", strret); + ok(context == space+1, "Expected space+1, got %p.\n", context); + + strret = p__mbstok_s( NULL, delim, &context); + ok(strret == NULL, "Expected NULL, got %p.\n", strret); + ok(context == space+1, "Expected space+1, got %p.\n", context); +} + START_TEST(msvcr90) { if(!init()) @@ -1576,4 +1662,6 @@ START_TEST(msvcr90) test_is_exception_typeof(); test__AdjustPointer(); test_mbstowcs(); + test_strtok_s(); + test__mbstok_s(); } diff --git a/dlls/msvcrt/mbcs.c b/dlls/msvcrt/mbcs.c index fe88cc7..93bb1a7 100644 --- a/dlls/msvcrt/mbcs.c +++ b/dlls/msvcrt/mbcs.c @@ -1205,7 +1205,10 @@ unsigned char* CDECL _mbstok_s_l(unsigned char *str, const unsigned char *delim, while((c=_mbsnextc(str)) && _mbschr(delim, c)) str += c>255 ? 2 : 1; if(!*str) + { + *ctx = str; return NULL; + }
*ctx = str + (c>255 ? 2 : 1); while((c=_mbsnextc(*ctx)) && !_mbschr(delim, c)) diff --git a/dlls/msvcrt/string.c b/dlls/msvcrt/string.c index 85f09ad..3e765d0 100644 --- a/dlls/msvcrt/string.c +++ b/dlls/msvcrt/string.c @@ -274,7 +274,10 @@ char * CDECL MSVCRT_strtok_s(char *str, const char *delim, char **ctx) while(*str && strchr(delim, *str)) str++; if(!*str) + { + *ctx = str; return NULL; + }
*ctx = str+1; while(**ctx && !strchr(delim, **ctx))