Alexandre Julliard : kernelbase: Support UTF-8 as default Ansi codepage in WideCharToMultiByte().
Alexandre Julliard
julliard at winehq.org
Mon Apr 11 15:54:59 CDT 2022
Module: wine
Branch: master
Commit: 1790546d03d8f61e0b01c17529e5ac88b31e1752
URL: https://source.winehq.org/git/wine.git/?a=commit;h=1790546d03d8f61e0b01c17529e5ac88b31e1752
Author: Alexandre Julliard <julliard at winehq.org>
Date: Mon Apr 11 17:27:34 2022 +0200
kernelbase: Support UTF-8 as default Ansi codepage in WideCharToMultiByte().
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/kernel32/tests/codepage.c | 16 ++++++-------
dlls/kernelbase/locale.c | 54 +++++++++++++++---------------------------
2 files changed, 27 insertions(+), 43 deletions(-)
diff --git a/dlls/kernel32/tests/codepage.c b/dlls/kernel32/tests/codepage.c
index b0dbd812346..0a5185d1804 100644
--- a/dlls/kernel32/tests/codepage.c
+++ b/dlls/kernel32/tests/codepage.c
@@ -263,32 +263,32 @@ static void test_other_invalid_parameters(void)
ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%lx\n", len, GetLastError());
- /* CP_UTF7, CP_UTF8, or CP_SYMBOL and defchar not NULL => ERROR_INVALID_PARAMETER */
- /* CP_SYMBOL's behavior here is undocumented */
+ /* CP_UTF7 or CP_SYMBOL and defchar not NULL => ERROR_INVALID_PARAMETER */
+ /* CP_UTF8 allows it since win10 1709 */
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=%lx\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)
- || broken(len == 12) /* Win10 1709+ */, "len=%d error=%lx\n", len, GetLastError());
+ ok(len == 12 || broken(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER),
+ "len=%d error=%lx\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=%lx\n", len, GetLastError());
- /* CP_UTF7, CP_UTF8, or CP_SYMBOL and used not NULL => ERROR_INVALID_PARAMETER */
- /* CP_SYMBOL's behavior here is undocumented */
+ /* CP_UTF7 or CP_SYMBOL and used not NULL => ERROR_INVALID_PARAMETER */
+ /* CP_UTF8 allows it since win10 1709 */
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=%lx\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)
- || broken(len == 12) /* Win10 1709+ */, "len=%d error=%lx\n", len, GetLastError());
+ ok(len == 12 || broken(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER),
+ "len=%d error=%lx\n", len, GetLastError());
SetLastError(0xdeadbeef);
len = WideCharToMultiByte(CP_SYMBOL, 0, w_string, w_string_len, c_string, c_string_len, NULL, &used);
diff --git a/dlls/kernelbase/locale.c b/dlls/kernelbase/locale.c
index c807b1e0124..358aa8c123c 100644
--- a/dlls/kernelbase/locale.c
+++ b/dlls/kernelbase/locale.c
@@ -2687,17 +2687,7 @@ static int wcstombs_utf8( DWORD flags, const WCHAR *src, int srclen, char *dst,
DWORD reslen;
NTSTATUS status;
- if (defchar || used)
- {
- SetLastError( ERROR_INVALID_PARAMETER );
- return 0;
- }
- if (flags & ~(WC_DISCARDNS | WC_SEPCHARS | WC_DEFAULTCHAR | WC_ERR_INVALID_CHARS |
- WC_COMPOSITECHECK | WC_NO_BEST_FIT_CHARS))
- {
- SetLastError( ERROR_INVALID_FLAGS );
- return 0;
- }
+ if (used) *used = FALSE;
if (!dstlen) dst = NULL;
status = RtlUnicodeToUTF8N( dst, dstlen, &reslen, src, srclen * sizeof(WCHAR) );
if (status == STATUS_SOME_NOT_MAPPED)
@@ -2707,6 +2697,7 @@ static int wcstombs_utf8( DWORD flags, const WCHAR *src, int srclen, char *dst,
SetLastError( ERROR_NO_UNICODE_TRANSLATION );
return 0;
}
+ if (used) *used = TRUE;
}
else if (!set_ntstatus( status )) reslen = 0;
return reslen;
@@ -3054,22 +3045,9 @@ static int wcstombs_dbcs_slow( const CPTABLEINFO *info, DWORD flags, const WCHAR
}
-static int wcstombs_codepage( UINT codepage, DWORD flags, const WCHAR *src, int srclen,
+static int wcstombs_codepage( const CPTABLEINFO *info, DWORD flags, const WCHAR *src, int srclen,
char *dst, int dstlen, const char *defchar, BOOL *used )
{
- const CPTABLEINFO *info = get_codepage_table( codepage );
-
- if (!info)
- {
- SetLastError( ERROR_INVALID_PARAMETER );
- return 0;
- }
- if (flags & ~(WC_DISCARDNS | WC_SEPCHARS | WC_DEFAULTCHAR | WC_ERR_INVALID_CHARS |
- WC_COMPOSITECHECK | WC_NO_BEST_FIT_CHARS))
- {
- SetLastError( ERROR_INVALID_FLAGS );
- return 0;
- }
if (flags || defchar || used)
{
if (!defchar) defchar = (const char *)&info->DefaultChar;
@@ -6468,6 +6446,7 @@ DWORD WINAPI DECLSPEC_HOTPATCH VerLanguageNameW( DWORD lang, LPWSTR buffer, DWOR
INT WINAPI DECLSPEC_HOTPATCH WideCharToMultiByte( UINT codepage, DWORD flags, LPCWSTR src, INT srclen,
LPSTR dst, INT dstlen, LPCSTR defchar, BOOL *used )
{
+ const CPTABLEINFO *info;
int ret;
if (!src || !srclen || (!dst && dstlen) || dstlen < 0)
@@ -6486,20 +6465,25 @@ INT WINAPI DECLSPEC_HOTPATCH WideCharToMultiByte( UINT codepage, DWORD flags, LP
case CP_UTF7:
ret = wcstombs_utf7( flags, src, srclen, dst, dstlen, defchar, used );
break;
- case CP_UTF8:
- ret = wcstombs_utf8( flags, src, srclen, dst, dstlen, defchar, used );
- break;
case CP_UNIXCP:
- if (unix_cp == CP_UTF8)
- {
- if (used) *used = FALSE;
- ret = wcstombs_utf8( flags, src, srclen, dst, dstlen, NULL, NULL );
- break;
- }
codepage = unix_cp;
/* fall through */
default:
- ret = wcstombs_codepage( codepage, flags, src, srclen, dst, dstlen, defchar, used );
+ if (!(info = get_codepage_table( codepage )))
+ {
+ SetLastError( ERROR_INVALID_PARAMETER );
+ return 0;
+ }
+ if (flags & ~(WC_DISCARDNS | WC_SEPCHARS | WC_DEFAULTCHAR | WC_ERR_INVALID_CHARS |
+ WC_COMPOSITECHECK | WC_NO_BEST_FIT_CHARS))
+ {
+ SetLastError( ERROR_INVALID_FLAGS );
+ return 0;
+ }
+ if (info->CodePage == CP_UTF8)
+ ret = wcstombs_utf8( flags, src, srclen, dst, dstlen, defchar, used );
+ else
+ ret = wcstombs_codepage( info, flags, src, srclen, dst, dstlen, defchar, used );
break;
}
TRACE( "cp %d %s -> %s, ret = %d\n", codepage, debugstr_wn(src, srclen), debugstr_an(dst, ret), ret );
More information about the wine-cvs
mailing list