Commit 8ccf747d authored by Alex Henrie's avatar Alex Henrie Committed by Alexandre Julliard

kernel32: Correct WideCharToMultiByte and MultiByteToWideChar error codes and conditions.

parent 92b4979b
......@@ -1878,7 +1878,7 @@ INT WINAPI MultiByteToWideChar( UINT page, DWORD flags, LPCSTR src, INT srclen,
const union cptable *table;
int ret;
if (!src || (!dst && dstlen))
if (!src || !srclen || (!dst && dstlen))
{
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
......@@ -1889,14 +1889,19 @@ INT WINAPI MultiByteToWideChar( UINT page, DWORD flags, LPCSTR src, INT srclen,
switch(page)
{
case CP_SYMBOL:
if( flags)
if (flags)
{
SetLastError( ERROR_INVALID_PARAMETER );
SetLastError( ERROR_INVALID_FLAGS );
return 0;
}
ret = wine_cpsymbol_mbstowcs( src, srclen, dst, dstlen );
break;
case CP_UTF7:
if (flags)
{
SetLastError( ERROR_INVALID_FLAGS );
return 0;
}
FIXME("UTF-7 not supported\n");
SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
return 0;
......@@ -1969,7 +1974,7 @@ INT WINAPI WideCharToMultiByte( UINT page, DWORD flags, LPCWSTR src, INT srclen,
const union cptable *table;
int ret, used_tmp;
if (!src || (!dst && dstlen))
if (!src || !srclen || (!dst && dstlen))
{
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
......@@ -1980,7 +1985,13 @@ INT WINAPI WideCharToMultiByte( UINT page, DWORD flags, LPCWSTR src, INT srclen,
switch(page)
{
case CP_SYMBOL:
if( flags || defchar || used)
/* when using CP_SYMBOL, ERROR_INVALID_FLAGS takes precedence */
if (flags)
{
SetLastError( ERROR_INVALID_FLAGS );
return 0;
}
if (defchar || used)
{
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
......@@ -1988,6 +1999,17 @@ INT WINAPI WideCharToMultiByte( UINT page, DWORD flags, LPCWSTR src, INT srclen,
ret = wine_cpsymbol_wcstombs( src, srclen, dst, dstlen );
break;
case CP_UTF7:
/* when using CP_UTF7, ERROR_INVALID_PARAMETER takes precedence */
if (defchar || used)
{
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
if (flags)
{
SetLastError( ERROR_INVALID_FLAGS );
return 0;
}
FIXME("UTF-7 not supported\n");
SetLastError( ERROR_CALL_NOT_IMPLEMENTED );
return 0;
......@@ -2000,7 +2022,11 @@ INT WINAPI WideCharToMultiByte( UINT page, DWORD flags, LPCWSTR src, INT srclen,
}
/* fall through */
case CP_UTF8:
if (used) *used = FALSE; /* all chars are valid for UTF-8 */
if (defchar || used)
{
SetLastError( ERROR_INVALID_PARAMETER );
return 0;
}
ret = wine_utf8_wcstombs( flags, src, srclen, dst, dstlen );
break;
default:
......
......@@ -189,6 +189,74 @@ static void test_negative_dest_length(void)
}
static void test_other_invalid_parameters(void)
{
char c_string[] = "Hello World";
size_t c_string_len = sizeof(c_string);
WCHAR w_string[] = {'H','e','l','l','o',' ','W','o','r','l','d',0};
size_t w_string_len = sizeof(w_string) / sizeof(WCHAR);
BOOL used;
INT len;
/* srclen=0 => ERROR_INVALID_PARAMETER */
SetLastError(0xdeadbeef);
len = WideCharToMultiByte(CP_ACP, 0, w_string, 0, c_string, c_string_len, NULL, NULL);
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
SetLastError(0xdeadbeef);
len = MultiByteToWideChar(CP_ACP, 0, c_string, 0, w_string, w_string_len);
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
/* dst=NULL but dstlen not 0 => ERROR_INVALID_PARAMETER */
SetLastError(0xdeadbeef);
len = WideCharToMultiByte(CP_ACP, 0, w_string, w_string_len, NULL, c_string_len, NULL, NULL);
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
SetLastError(0xdeadbeef);
len = MultiByteToWideChar(CP_ACP, 0, c_string, c_string_len, NULL, w_string_len);
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
/* CP_UTF7, CP_UTF8, or CP_SYMBOL and defchar not NULL => ERROR_INVALID_PARAMETER */
/* CP_SYMBOL's behavior here is undocumented */
SetLastError(0xdeadbeef);
len = WideCharToMultiByte(CP_UTF7, 0, w_string, w_string_len, c_string, c_string_len, c_string, NULL);
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
SetLastError(0xdeadbeef);
len = WideCharToMultiByte(CP_UTF8, 0, w_string, w_string_len, c_string, c_string_len, c_string, NULL);
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
SetLastError(0xdeadbeef);
len = WideCharToMultiByte(CP_SYMBOL, 0, w_string, w_string_len, c_string, c_string_len, c_string, NULL);
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
/* CP_UTF7, CP_UTF8, or CP_SYMBOL and used not NULL => ERROR_INVALID_PARAMETER */
/* CP_SYMBOL's behavior here is undocumented */
SetLastError(0xdeadbeef);
len = WideCharToMultiByte(CP_UTF7, 0, w_string, w_string_len, c_string, c_string_len, NULL, &used);
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
SetLastError(0xdeadbeef);
len = WideCharToMultiByte(CP_UTF8, 0, w_string, w_string_len, c_string, c_string_len, NULL, &used);
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
SetLastError(0xdeadbeef);
len = WideCharToMultiByte(CP_SYMBOL, 0, w_string, w_string_len, c_string, c_string_len, NULL, &used);
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
/* CP_UTF7, flags not 0 and used not NULL => ERROR_INVALID_PARAMETER */
/* (tests precedence of ERROR_INVALID_PARAMETER over ERROR_INVALID_FLAGS) */
/* The same test with CP_SYMBOL instead of CP_UTF7 gives ERROR_INVALID_FLAGS
instead except on Windows NT4 */
SetLastError(0xdeadbeef);
len = WideCharToMultiByte(CP_UTF7, 1, w_string, w_string_len, c_string, c_string_len, NULL, &used);
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
}
static void test_overlapped_buffers(void)
{
static const WCHAR strW[] = {'j','u','s','t',' ','a',' ','t','e','s','t',0};
......@@ -402,6 +470,7 @@ START_TEST(codepage)
test_null_source();
test_negative_source_length();
test_negative_dest_length();
test_other_invalid_parameters();
test_overlapped_buffers();
/* WideCharToMultiByte has two code paths, test both here */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment