From 0b95ebd283986fa179c7ec6d2ea3f34c977c3aaf Mon Sep 17 00:00:00 2001 From: Alex Henrie Date: Mon, 27 Mar 2017 21:59:05 -0600 Subject: [PATCH] kernel32: Check for invalid flags in codepage conversion functions. Signed-off-by: Alex Henrie Signed-off-by: Alexandre Julliard --- dlls/kernel32/locale.c | 23 ++++++++++++++++++++ dlls/kernel32/tests/codepage.c | 39 ++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/dlls/kernel32/locale.c b/dlls/kernel32/locale.c index ca5975137f1..e14aedbe44c 100644 --- a/dlls/kernel32/locale.c +++ b/dlls/kernel32/locale.c @@ -54,6 +54,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(nls); #define LOCALE_LOCALEINFOFLAGSMASK (LOCALE_NOUSEROVERRIDE|LOCALE_USE_CP_ACP|\ LOCALE_RETURN_NUMBER|LOCALE_RETURN_GENITIVE_NAMES) +#define MB_FLAGSMASK (MB_PRECOMPOSED|MB_COMPOSITE|MB_USEGLYPHCHARS|MB_ERR_INVALID_CHARS) +#define WC_FLAGSMASK (WC_DISCARDNS|WC_SEPCHARS|WC_DEFAULTCHAR|WC_ERR_INVALID_CHARS|\ + WC_COMPOSITECHECK|WC_NO_BEST_FIT_CHARS) /* current code pages */ static const union cptable *ansi_cptable; @@ -2422,6 +2425,11 @@ INT WINAPI MultiByteToWideChar( UINT page, DWORD flags, LPCSTR src, INT srclen, #endif /* fall through */ case CP_UTF8: + if (flags & ~MB_FLAGSMASK) + { + SetLastError( ERROR_INVALID_FLAGS ); + return 0; + } ret = wine_utf8_mbstowcs( flags, src, srclen, dst, dstlen ); break; default: @@ -2430,6 +2438,11 @@ INT WINAPI MultiByteToWideChar( UINT page, DWORD flags, LPCSTR src, INT srclen, SetLastError( ERROR_INVALID_PARAMETER ); return 0; } + if (flags & ~MB_FLAGSMASK) + { + SetLastError( ERROR_INVALID_FLAGS ); + return 0; + } ret = wine_cp_mbstowcs( table, flags, src, srclen, dst, dstlen ); break; } @@ -2653,6 +2666,11 @@ INT WINAPI WideCharToMultiByte( UINT page, DWORD flags, LPCWSTR src, INT srclen, SetLastError( ERROR_INVALID_PARAMETER ); return 0; } + if (flags & ~WC_FLAGSMASK) + { + SetLastError( ERROR_INVALID_FLAGS ); + return 0; + } ret = wine_utf8_wcstombs( flags, src, srclen, dst, dstlen ); break; default: @@ -2661,6 +2679,11 @@ INT WINAPI WideCharToMultiByte( UINT page, DWORD flags, LPCWSTR src, INT srclen, SetLastError( ERROR_INVALID_PARAMETER ); return 0; } + if (flags & ~WC_FLAGSMASK) + { + SetLastError( ERROR_INVALID_FLAGS ); + return 0; + } ret = wine_cp_wcstombs( table, flags, src, srclen, dst, dstlen, defchar, used ? &used_tmp : NULL ); if (used) *used = used_tmp; diff --git a/dlls/kernel32/tests/codepage.c b/dlls/kernel32/tests/codepage.c index 8eccf9990e0..7389d93276f 100644 --- a/dlls/kernel32/tests/codepage.c +++ b/dlls/kernel32/tests/codepage.c @@ -209,6 +209,40 @@ static void test_other_invalid_parameters(void) BOOL used; INT len; + /* Unrecognized flag => ERROR_INVALID_FLAGS */ + SetLastError(0xdeadbeef); + len = WideCharToMultiByte(CP_ACP, 0x100, w_string, -1, c_string, c_string_len, NULL, NULL); + ok(len == 0 && GetLastError() == ERROR_INVALID_FLAGS, "len=%d error=%x\n", len, GetLastError()); + + SetLastError(0xdeadbeef); + len = WideCharToMultiByte(CP_ACP, 0x800, w_string, -1, c_string, c_string_len, NULL, NULL); + ok(len == 0 && GetLastError() == ERROR_INVALID_FLAGS, "len=%d error=%x\n", len, GetLastError()); + + SetLastError(0xdeadbeef); + len = MultiByteToWideChar(CP_ACP, 0x10, c_string, -1, w_string, w_string_len); + ok(len == 0 && GetLastError() == ERROR_INVALID_FLAGS, "len=%d error=%x\n", len, GetLastError()); + + + /* Unrecognized flag and invalid codepage => ERROR_INVALID_PARAMETER */ + SetLastError(0xdeadbeef); + len = WideCharToMultiByte(0xdeadbeef, 0x100, w_string, w_string_len, 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(0xdeadbeef, 0x10, c_string, c_string_len, w_string, w_string_len); + ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError()); + + + /* Unrecognized flag and src is NULL => ERROR_INVALID_PARAMETER */ + SetLastError(0xdeadbeef); + len = WideCharToMultiByte(CP_ACP, 0x100, NULL, -1, 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, 0x10, NULL, -1, w_string, w_string_len); + ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError()); + + /* srclen=0 => ERROR_INVALID_PARAMETER */ SetLastError(0xdeadbeef); len = WideCharToMultiByte(CP_ACP, 0, w_string, 0, c_string, c_string_len, NULL, NULL); @@ -266,6 +300,11 @@ static void test_other_invalid_parameters(void) 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()); + + /* CP_UTF8, unrecognized flag and used not NULL => ERROR_INVALID_PARAMETER */ + SetLastError(0xdeadbeef); + len = WideCharToMultiByte(CP_UTF8, 0x100, 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)