Module: wine Branch: master Commit: 8ccf747d6a7c05f64559949705548e2158b85eea URL: http://source.winehq.org/git/wine.git/?a=commit;h=8ccf747d6a7c05f64559949705...
Author: Alex Henrie alexhenrie24@gmail.com Date: Wed May 16 19:24:03 2012 -0600
kernel32: Correct WideCharToMultiByte and MultiByteToWideChar error codes and conditions.
---
dlls/kernel32/locale.c | 38 ++++++++++++++++++--- dlls/kernel32/tests/codepage.c | 69 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 6 deletions(-)
diff --git a/dlls/kernel32/locale.c b/dlls/kernel32/locale.c index 380c616..2970856 100644 --- a/dlls/kernel32/locale.c +++ b/dlls/kernel32/locale.c @@ -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: diff --git a/dlls/kernel32/tests/codepage.c b/dlls/kernel32/tests/codepage.c index 61bcf54..c980348 100644 --- a/dlls/kernel32/tests/codepage.c +++ b/dlls/kernel32/tests/codepage.c @@ -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 */