From 702b13fc0fa8714a12089aa189c7cb4022024ae4 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Wed, 19 Sep 2012 21:20:09 +0000 Subject: [PATCH] [CRT_APITEST] Add tests for mbstowcs_s svn path=/trunk/; revision=57343 --- rostests/apitests/crt/mbstowcs_s.c | 360 ++++++++++++++++++ .../apitests/crt/msvcrt_crt_apitest.cmake | 2 +- rostests/apitests/crt/testlist.c | 2 + 3 files changed, 363 insertions(+), 1 deletion(-) create mode 100644 rostests/apitests/crt/mbstowcs_s.c diff --git a/rostests/apitests/crt/mbstowcs_s.c b/rostests/apitests/crt/mbstowcs_s.c new file mode 100644 index 00000000000..8037c84a18c --- /dev/null +++ b/rostests/apitests/crt/mbstowcs_s.c @@ -0,0 +1,360 @@ +/* + * PROJECT: ReactOS api tests + * LICENSE: GPL - See COPYING in the top level directory + * PURPOSE: Test for mbstowcs_s + */ + +#define WIN32_NO_STATUS +#include +#include +#include +#include + +#define ok_errno(x) ok_hex(errno, (x)) + +errno_t +mbstowcs_s( + size_t *returnval, + wchar_t *widechar, + size_t charoutct, + const char *multibyte, + size_t count); + +void +_invalid_parameter( + const wchar_t * expression, + const wchar_t * function, + const wchar_t * file, + unsigned int line, + uintptr_t pReserved); + +void +_invalid_parameterA( + const char * expression, + const char * function, + const char * file, + unsigned int line, + uintptr_t pReserved) +{ + // call _invalid_parameter +} + +#define MSVCRT_INVALID_PMT(x) _invalid_parameterA(#x, __FUNCTION__, __FILE__, __LINE__, 0) +#define MSVCRT_CHECK_PMT(x) ((x) || (MSVCRT_INVALID_PMT(x),0)) + +#define _mbsnlen strnlen + +errno_t +mbstowcs_s( + _Out_opt_ size_t *pReturnValue, + _Out_ wchar_t *pwcstr, + _In_ size_t sizeInWords, + _In_ const char *pmbstr, + _In_ size_t count) +{ + size_t cchMax, cwcWritten; + errno_t retval = 0; + + if (!MSVCRT_CHECK_PMT( ((sizeInWords != 0) && (pwcstr != 0)) || + ((sizeInWords == 0) && (pwcstr == 0)) )) + { + _set_errno(EINVAL); + return EINVAL; + } + + /* Check if we have a return value pointer */ + if (pReturnValue) + { + /* Default to 0 bytes written */ + *pReturnValue = 0; + } + + if (!MSVCRT_CHECK_PMT((count == 0) || (pmbstr != 0))) + { + _set_errno(EINVAL); + return EINVAL; + } + + /* Check if there is anything to do */ + if ((pwcstr == 0) && (pmbstr == 0)) + { + _set_errno(EINVAL); + return EINVAL; + } + + /* Check if we have a source string */ + if (pmbstr) + { + /* Check if we also have a wchar buffer */ + if (pwcstr) + { + /* Calculate the maximum the we can write */ + cchMax = (count < sizeInWords) ? count + 1 : sizeInWords; + + /* Now do the conversion */ + cwcWritten = mbstowcs(pwcstr, pmbstr, cchMax); + + /* Check if the buffer was not zero terminated */ + if (cwcWritten == cchMax) + { + /* Check if we reached the max size of the dest buffer */ + if (cwcWritten == sizeInWords) + { + /* Does the caller allow this? */ + if (count != _TRUNCATE) + { + /* Not allowed, truncate to 0 length */ + pwcstr[0] = L'\0'; + + /* Return error */ + _set_errno(ERANGE); + return ERANGE; + } + + /* Inform the caller about truncation */ + retval = STRUNCATE; + } + + /* zero teminate the buffer */ + pwcstr[cwcWritten - 1] = L'\0'; + } + else + { + /* The buffer is zero terminated, count the terminating char */ + cwcWritten++; + } + } + else + { + /* Get the length of the string, plus 0 terminator */ + cwcWritten = _mbsnlen(pmbstr, count) + 1; + } + } + else + { + cwcWritten = count + 1; + } + + /* Check if we have a return value pointer */ + if (pReturnValue) + { + /* Default to 0 bytes written */ + *pReturnValue = cwcWritten; + } + + return retval; +} + + + +wchar_t g_expression[64]; +wchar_t g_function[64]; +wchar_t g_file[128]; +unsigned int g_line; +uintptr_t g_pReserved; + +void +_test_invalid_parameter( + const wchar_t * expression, + const wchar_t * function, + const wchar_t * file, + unsigned int line, + uintptr_t pReserved) +{ + wcsncpy(g_expression, expression, sizeof(g_expression) / sizeof(wchar_t)); + wcsncpy(g_function, function, sizeof(g_function) / sizeof(wchar_t)); + wcsncpy(g_file, file, sizeof(g_file) / sizeof(wchar_t)); + g_line = line; + g_pReserved = pReserved; +} + +START_TEST(mbstowcs_s) +{ +// _set_invalid_parameter_handler(_test_invalid_parameter); + + errno_t ret; + size_t returnval; + wchar_t widechar[10]; +#if 1 + _set_errno(0); + returnval = 0xf00bac; + widechar[5] = 0xFF; + ret = mbstowcs_s(&returnval, widechar, 6, "hallo", 5); + ok_long(ret, 0); + ok_size_t(returnval, 6); + ok_char(widechar[5], 0); + ok_wstr(widechar, L"hallo"); + ok_errno(0); + + _set_errno(0); + returnval = 0xf00bac; + widechar[0] = 0xFF; + ret = mbstowcs_s(&returnval, widechar, 1, "", 0); + ok_long(ret, 0); + ok_size_t(returnval, 1); + ok_char(widechar[0], 0); + ok_errno(0); + + _set_errno(0); + returnval = 0xf00bac; + widechar[0] = 0xFF; + widechar[1] = 0xFF; + widechar[2] = 0xFF; + widechar[3] = 0xFF; + widechar[4] = 0xFF; + widechar[5] = 0xFF; + ret = mbstowcs_s(&returnval, widechar, 5, "hallo", 5); + ok_long(ret, ERANGE); + ok_size_t(returnval, 0); + ok_char(widechar[5], 0xFF); + ok_char(widechar[4], L'o'); + ok_char(widechar[3], L'l'); + ok_char(widechar[2], L'l'); + ok_char(widechar[1], L'a'); + ok_char(widechar[0], 0); + ok_errno(ERANGE); + + _set_errno(0); + returnval = 0xf00bac; + widechar[0] = 0xFF; + widechar[1] = 0xFF; + widechar[2] = 0xFF; + widechar[3] = 0xFF; + widechar[4] = 0xFF; + widechar[5] = 0xFF; + ret = mbstowcs_s(&returnval, widechar, 3, "hallo", 5); + ok_long(ret, ERANGE); + ok_size_t(returnval, 0); + ok_char(widechar[5], 0xFF); + ok_char(widechar[4], 0xFF); + ok_char(widechar[3], 0xFF); + ok_char(widechar[2], L'l'); + ok_char(widechar[1], L'a'); + ok_char(widechar[0], 0); + ok_errno(ERANGE); + + _set_errno(0); + ret = mbstowcs_s(0, 0, 0, 0, 0); + ok_long(ret, EINVAL); + ok_errno(EINVAL); + + _set_errno(0); + returnval = 0xf00bac; + ret = mbstowcs_s(&returnval, 0, 0, 0, 0); + ok_long(ret, EINVAL); + ok_size_t(returnval, 0); + ok_errno(EINVAL); + + _set_errno(0); + widechar[0] = L'x'; + ret = mbstowcs_s(0, widechar, 0, 0, 0); + ok_long(ret, EINVAL); + ok_char(widechar[0], L'x'); + ok_errno(EINVAL); + + _set_errno(0); + ret = mbstowcs_s(0, widechar, 10, "hallo", 5); + ok_long(ret, 0); + ok_errno(0); + + _set_errno(0); + ret = mbstowcs_s(0, widechar, 0, "hallo", 5); + ok_long(ret, EINVAL); + ok_errno(EINVAL); + + _set_errno(0); + returnval = 0xf00bac; + ret = mbstowcs_s(&returnval, 0, 10, "hallo", 5); + ok_long(ret, EINVAL); + ok_size_t(returnval, 0xf00bac); + ok_errno(EINVAL); + + _set_errno(0); + returnval = 0xf00bac; + ret = mbstowcs_s(&returnval, 0, 0, "hallo", 5); + ok_long(ret, 0); + ok_size_t(returnval, 6); + ok_errno(0); + + _set_errno(0); + returnval = 0xf00bac; + ret = mbstowcs_s(&returnval, widechar, 10, 0, 5); + ok_long(ret, EINVAL); + ok_size_t(returnval, 0); + ok_errno(EINVAL); + + _set_errno(0); + returnval = 0xf00bac; + ret = mbstowcs_s(&returnval, widechar, 10, "hallo", 0); + ok_long(ret, 0); + ok_size_t(returnval, 1); + ok_errno(0); +#endif + _set_errno(0); + returnval = 0xf00bac; + widechar[0] = 0xABCD; + widechar[1] = 0xABCD; + widechar[2] = 0xABCD; + widechar[3] = 0xABCD; + widechar[4] = 0xABCD; + widechar[5] = 0xABCD; + ret = mbstowcs_s(&returnval, widechar, 10, "hallo", 2); + ok_long(ret, 0); + ok_size_t(returnval, 3); + ok_char(widechar[5], 0xABCD); + ok_char(widechar[4], 0xABCD); + ok_char(widechar[3], 0xABCD); + ok_char(widechar[2], 0); + ok_char(widechar[1], L'a'); + ok_char(widechar[0], L'h'); + ok_errno(0); +#if 1 + _set_errno(0); + returnval = 0xf00bac; + ret = mbstowcs_s(&returnval, widechar, 10, 0, 0); + ok_long(ret, 0); + ok_size_t(returnval, 1); + ok_errno(0); + + _set_errno(0); + returnval = 0xf00bac; + ret = mbstowcs_s(&returnval, widechar, 10, "hallo", 7); + ok_long(ret, 0); + ok_size_t(returnval, 6); + ok_errno(0); + + _set_errno(0); + returnval = 0xf00bac; + ret = mbstowcs_s(&returnval, 0, 0, "hallo", 7); + ok_long(ret, 0); + ok_size_t(returnval, 6); + ok_errno(0); + + _set_errno(0); + returnval = 0xf00bac; + widechar[0] = 0xABCD; + widechar[1] = 0xABCD; + widechar[2] = 0xABCD; + widechar[3] = 0xABCD; + widechar[4] = 0xABCD; + widechar[5] = 0xABCD; + ret = mbstowcs_s(&returnval, widechar, 5, "hallo", _TRUNCATE); + ok_long(ret, STRUNCATE); + ok_size_t(returnval, 5); + ok_char(widechar[5], 0xABCD); + ok_char(widechar[4], 0); + ok_char(widechar[3], L'l'); + ok_char(widechar[2], L'l'); + ok_char(widechar[1], L'a'); + ok_char(widechar[0], L'h'); + ok_errno(0); + + _set_errno(0); + returnval = 0xf00bac; + ret = mbstowcs_s(&returnval, widechar, 10, "hallo", -1); + ok_long(ret, 0); + ok_size_t(returnval, 6); + ok_errno(0); +#endif + +} diff --git a/rostests/apitests/crt/msvcrt_crt_apitest.cmake b/rostests/apitests/crt/msvcrt_crt_apitest.cmake index 04880a3eb52..9ce4ec2ad9a 100644 --- a/rostests/apitests/crt/msvcrt_crt_apitest.cmake +++ b/rostests/apitests/crt/msvcrt_crt_apitest.cmake @@ -1118,7 +1118,7 @@ list(APPEND SOURCE_MSVCRT # mbsrtowcs # mbsrtowcs_s # mbstowcs.c -# mbstowcs_s + mbstowcs_s # mbtowc.c # memchr.c # memcmp.c diff --git a/rostests/apitests/crt/testlist.c b/rostests/apitests/crt/testlist.c index f84b4959381..c97b02c41ed 100644 --- a/rostests/apitests/crt/testlist.c +++ b/rostests/apitests/crt/testlist.c @@ -6,6 +6,7 @@ #include "wine/test.h" #if defined(TEST_MSVCRT) +extern void func_mbstowcs_s(void); extern void func__vscprintf(void); extern void func__vscwprintf(void); #endif @@ -31,6 +32,7 @@ const struct test winetest_testlist[] = #endif #if defined(TEST_STATIC_CRT) #elif defined(TEST_MSVCRT) + { "mbstowcs_s", func_mbstowcs_s }, { "_vscprintf", func__vscprintf }, { "_vscwprintf", func__vscwprintf }, #elif defined(TEST_NTDLL)