w32: Always use Unicode for console input and output.

* common/init.c (_init_common_subsystems) [W32]: Set the codepage to
UTF-8 for input and putput.  Switch gettext to UTF-8.
* tools/gpgconf.c (main): Display the input and output codepage if
they differ.
* g10/gpg.c (utf8_strings) [W32]: Make sure this is always set.
--

With this patch the former patch to use ReadConsoleW and WriteConsoleW
in ttyio.c are kind of superfluous because the ANSI version of these
functions are also able to read/write UTF-8 directly given the console
code page has been set correctly.  However, this seems to work only
with recent versions of Windows-10.

GnuPG-bug-id: 4365
This commit is contained in:
Werner Koch 2021-03-05 15:33:40 +01:00
parent 31b708e268
commit 8c41b8aac3
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
4 changed files with 41 additions and 9 deletions

View File

@ -202,6 +202,17 @@ _init_common_subsystems (gpg_err_source_t errsource, int *argcp, char ***argvp)
parse_std_file_handles (argcp, argvp); parse_std_file_handles (argcp, argvp);
#endif #endif
#ifdef HAVE_W32_SYSTEM
/* We want gettext to always output UTF-8 and we put the console in
* utf-8 mode. */
gettext_use_utf8 (1);
if (!SetConsoleCP (CP_UTF8) || !SetConsoleOutputCP (CP_UTF8))
{
log_info ("SetConsoleCP failed: %s\n", w32_strerror (-1));
log_info ("Warning: Garbled console data possible\n");
}
#endif
/* Access the standard estreams as early as possible. If we don't /* Access the standard estreams as early as possible. If we don't
do this the original stdio streams may have been closed when do this the original stdio streams may have been closed when
_es_get_std_stream is first use and in turn it would connect to _es_get_std_stream is first use and in turn it would connect to

View File

@ -1529,13 +1529,14 @@ not used).
@item --display-charset @var{name} @item --display-charset @var{name}
@opindex display-charset @opindex display-charset
Set the name of the native character set. This is used to convert Set the name of the native character set. This is used to convert some
some informational strings like user IDs to the proper UTF-8 encoding. informational strings like user IDs to the proper UTF-8 encoding.
Note that this has nothing to do with the character set of data to be Note that this has nothing to do with the character set of data to be
encrypted or signed; GnuPG does not recode user-supplied data. If encrypted or signed; GnuPG does not recode user-supplied data. If this
this option is not used, the default character set is determined from option is not used, the default character set is determined from the
the current locale. A verbosity level of 3 shows the chosen set. current locale. A verbosity level of 3 shows the chosen set. This
Valid values for @var{name} are: option should not be used on Windows. Valid values for @var{name}
are:
@table @asis @table @asis
@ -1571,6 +1572,12 @@ encoded in the character set as specified by
@option{--display-charset}. These options affect all following @option{--display-charset}. These options affect all following
arguments. Both options may be used multiple times. arguments. Both options may be used multiple times.
This option has no effect on Windows. There the internal used UTF-8
encoding is translated for console input and output. The command line
arguments are expected as Unicode and translated to UTF-8. Thus when
calling this program from another, make sure to use the Unicode
version of CreateProcess.
@anchor{gpg-option --options} @anchor{gpg-option --options}
@item --options @var{file} @item --options @var{file}
@opindex options @opindex options

View File

@ -1007,7 +1007,13 @@ static struct debug_flags_s debug_flags [] =
int g10_errors_seen = 0; int g10_errors_seen = 0;
static int utf8_strings = 0; static int utf8_strings =
#ifdef HAVE_W32_SYSTEM
1
#else
0
#endif
;
static int maybe_setuid = 1; static int maybe_setuid = 1;
static unsigned int opt_set_iobuf_size; static unsigned int opt_set_iobuf_size;
static unsigned int opt_set_iobuf_size_used; static unsigned int opt_set_iobuf_size_used;
@ -3406,7 +3412,11 @@ main (int argc, char **argv)
opt.verify_options&=~VERIFY_SHOW_NOTATIONS; opt.verify_options&=~VERIFY_SHOW_NOTATIONS;
break; break;
case oUtf8Strings: utf8_strings = 1; break; case oUtf8Strings: utf8_strings = 1; break;
case oNoUtf8Strings: utf8_strings = 0; break; case oNoUtf8Strings:
#ifdef HAVE_W32_SYSTEM
utf8_strings = 0;
#endif
break;
case oDisableCipherAlgo: case oDisableCipherAlgo:
{ {
int algo = string_to_cipher_algo (pargs.r.ret_str); int algo = string_to_cipher_algo (pargs.r.ret_str);

View File

@ -945,7 +945,11 @@ main (int argc, char **argv)
#ifdef HAVE_W32_SYSTEM #ifdef HAVE_W32_SYSTEM
{ {
get_outfp (&outfp); get_outfp (&outfp);
es_fprintf (outfp, "Console: CP%u\n", GetConsoleOutputCP ()); if (GetConsoleCP () != GetConsoleOutputCP ())
es_fprintf (outfp, "Console: CP%u/CP%u\n",
GetConsoleCP (), GetConsoleOutputCP ());
else
es_fprintf (outfp, "Console: CP%u\n", GetConsoleCP ());
es_fprintf (outfp, "ANSI: CP%u\n", GetACP ()); es_fprintf (outfp, "ANSI: CP%u\n", GetACP ());
es_fprintf (outfp, "OEM: CP%u\n", GetOEMCP ()); es_fprintf (outfp, "OEM: CP%u\n", GetOEMCP ());
} }