1
0
mirror of https://git.tartarus.org/simon/putty.git synced 2025-04-01 11:12:50 -05:00

Switch CONF_remote_cmd to being STR_AMBI.

The immediate usefulness of this is in pterm.exe: when the user uses
-e to specify a command to run in the pterm, we retrieve the command
in Unicode, store it in CONF_remote_cmd as UTF-8, and then in conpty.c
we can extract it in the same form and convert it back to Unicode to
pass losslessly to CreateProcessW. So now non-ACP Unicode works in
that part of the pterm command line.
This commit is contained in:
Simon Tatham 2024-09-26 10:50:47 +01:00
parent 7d9d72ba15
commit f80955488a
7 changed files with 31 additions and 22 deletions

4
conf.h
View File

@ -154,7 +154,7 @@ CONF_OPTION(proxy_log_to_term,
/* SSH options */ /* SSH options */
CONF_OPTION(remote_cmd, CONF_OPTION(remote_cmd,
VALUE_TYPE(STR), VALUE_TYPE(STR_AMBI),
DEFAULT_STR(""), DEFAULT_STR(""),
SAVE_KEYWORD("RemoteCommand"), SAVE_KEYWORD("RemoteCommand"),
) )
@ -165,7 +165,7 @@ CONF_OPTION(remote_cmd2,
* methods of running an SFTP server at the remote end); never set * methods of running an SFTP server at the remote end); never set
* by user configuration, or loaded or saved. * by user configuration, or loaded or saved.
*/ */
VALUE_TYPE(STR), VALUE_TYPE(STR_AMBI),
DEFAULT_STR(""), DEFAULT_STR(""),
NOT_SAVED, NOT_SAVED,
) )

View File

@ -182,7 +182,9 @@ static void mainchan_open_confirmation(Channel *chan)
if (mc->n_req_env) if (mc->n_req_env)
ppl_logevent("Sent %d environment variables", mc->n_req_env); ppl_logevent("Sent %d environment variables", mc->n_req_env);
cmd = conf_get_str(mc->conf, CONF_remote_cmd); /* Ignore encoding of CONF_remote_cmd so as not to disturb
* legacy handling of non-UTF-8 commands */
cmd = conf_get_str_ambi(mc->conf, CONF_remote_cmd, NULL);
if (conf_get_bool(mc->conf, CONF_ssh_subsys)) { if (conf_get_bool(mc->conf, CONF_ssh_subsys)) {
retry_cmd_now = !sshfwd_start_subsystem(mc->sc, true, cmd); retry_cmd_now = !sshfwd_start_subsystem(mc->sc, true, cmd);
} else if (*cmd) { } else if (*cmd) {
@ -205,7 +207,9 @@ static void mainchan_open_confirmation(Channel *chan)
static void mainchan_try_fallback_command(mainchan *mc) static void mainchan_try_fallback_command(mainchan *mc)
{ {
const char *cmd = conf_get_str(mc->conf, CONF_remote_cmd2); /* Ignore encoding of CONF_remote_cmd2 so as not to disturb legacy
* handling of non-UTF-8 commands */
const char *cmd = conf_get_str_ambi(mc->conf, CONF_remote_cmd2, NULL);
if (conf_get_bool(mc->conf, CONF_ssh_subsys2)) { if (conf_get_bool(mc->conf, CONF_ssh_subsys2)) {
sshfwd_start_subsystem(mc->sc, true, cmd); sshfwd_start_subsystem(mc->sc, true, cmd);
} else { } else {
@ -288,7 +292,7 @@ static void mainchan_request_response(Channel *chan, bool success)
if (success) { if (success) {
ppl_logevent("Started a shell/command"); ppl_logevent("Started a shell/command");
mainchan_ready(mc); mainchan_ready(mc);
} else if (*conf_get_str(mc->conf, CONF_remote_cmd2)) { } else if (*conf_get_str_ambi(mc->conf, CONF_remote_cmd2, NULL)) {
ppl_logevent("Primary command failed; attempting fallback"); ppl_logevent("Primary command failed; attempting fallback");
mainchan_try_fallback_command(mc); mainchan_try_fallback_command(mc);
} else { } else {

View File

@ -696,7 +696,7 @@ void test_simple(void)
test_str_simple(CONF_proxy_telnet_command, "ProxyTelnetCommand", "connect %host %port\\n"); test_str_simple(CONF_proxy_telnet_command, "ProxyTelnetCommand", "connect %host %port\\n");
test_int_translated(CONF_proxy_log_to_term, "ProxyLogToTerm", FORCE_OFF, test_int_translated(CONF_proxy_log_to_term, "ProxyLogToTerm", FORCE_OFF,
FORCE_ON, 0, FORCE_OFF, 1, AUTO, 2, -1); FORCE_ON, 0, FORCE_OFF, 1, AUTO, 2, -1);
test_str_simple(CONF_remote_cmd, "RemoteCommand", ""); test_str_ambi_simple(CONF_remote_cmd, "RemoteCommand", "", false);
test_bool_simple(CONF_nopty, "NoPTY", false); test_bool_simple(CONF_nopty, "NoPTY", false);
test_bool_simple(CONF_compression, "Compression", false); test_bool_simple(CONF_compression, "Compression", false);
test_bool_simple(CONF_ssh_prefer_known_hostkeys, "PreferKnownHostKeys", true); test_bool_simple(CONF_ssh_prefer_known_hostkeys, "PreferKnownHostKeys", true);

View File

@ -394,8 +394,8 @@ static SeatPromptResult plink_get_userpass_input(Seat *seat, prompts_t *p)
static bool plink_seat_interactive(Seat *seat) static bool plink_seat_interactive(Seat *seat)
{ {
return (!*conf_get_str(conf, CONF_remote_cmd) && return (!*conf_get_str_ambi(conf, CONF_remote_cmd, NULL) &&
!*conf_get_str(conf, CONF_remote_cmd2) && !*conf_get_str_ambi(conf, CONF_remote_cmd2, NULL) &&
!*conf_get_str(conf, CONF_ssh_nc_host)); !*conf_get_str(conf, CONF_ssh_nc_host));
} }

View File

@ -176,7 +176,7 @@ static char *conpty_init(const BackendVtable *vt, Seat *seat,
HPCON pcon; HPCON pcon;
bool pcon_needs_cleanup = false; bool pcon_needs_cleanup = false;
STARTUPINFOEX si; STARTUPINFOEXW si;
memset(&si, 0, sizeof(si)); memset(&si, 0, sizeof(si));
if (!init_conpty_api()) { if (!init_conpty_api()) {
@ -238,16 +238,21 @@ static char *conpty_init(const BackendVtable *vt, Seat *seat,
PROCESS_INFORMATION pi; PROCESS_INFORMATION pi;
memset(&pi, 0, sizeof(pi)); memset(&pi, 0, sizeof(pi));
char *command; wchar_t *command;
const char *conf_cmd = conf_get_str(conf, CONF_remote_cmd); {
if (*conf_cmd) { bool utf8;
command = dupstr(conf_cmd); const char *conf_cmd = conf_get_str_ambi(conf, CONF_remote_cmd, &utf8);
} else { if (*conf_cmd) {
command = dupcat(get_system_dir(), "\\cmd.exe"); command = dup_mb_to_wc(utf8 ? CP_UTF8 : CP_ACP, conf_cmd);
} else {
char *cmd = dupcat(get_system_dir(), "\\cmd.exe");
command = dup_mb_to_wc(CP_ACP, cmd);
sfree(cmd);
}
} }
bool created_ok = CreateProcess(NULL, command, NULL, NULL, bool created_ok = CreateProcessW(NULL, command, NULL, NULL,
false, EXTENDED_STARTUPINFO_PRESENT, false, EXTENDED_STARTUPINFO_PRESENT,
NULL, NULL, &si.StartupInfo, &pi); NULL, NULL, &si.StartupInfo, &pi);
sfree(command); sfree(command);
if (!created_ok) { if (!created_ok) {
err = dupprintf("CreateProcess: %s", err = dupprintf("CreateProcess: %s",

View File

@ -82,8 +82,8 @@ static SeatPromptResult plink_get_userpass_input(Seat *seat, prompts_t *p)
static bool plink_seat_interactive(Seat *seat) static bool plink_seat_interactive(Seat *seat)
{ {
return (!*conf_get_str(conf, CONF_remote_cmd) && return (!*conf_get_str_ambi(conf, CONF_remote_cmd, NULL) &&
!*conf_get_str(conf, CONF_remote_cmd2) && !*conf_get_str_ambi(conf, CONF_remote_cmd2, NULL) &&
!*conf_get_str(conf, CONF_ssh_nc_host)); !*conf_get_str(conf, CONF_ssh_nc_host));
} }

View File

@ -32,8 +32,8 @@ void gui_term_process_cmdline(Conf *conf, char *cmdline)
if (nextarg) { if (nextarg) {
/* The command to execute is taken to be the unparsed /* The command to execute is taken to be the unparsed
* version of the whole remainder of the command line. */ * version of the whole remainder of the command line. */
char *cmd = cmdline_arg_remainder_acp(nextarg); char *cmd = cmdline_arg_remainder_utf8(nextarg);
conf_set_str(conf, CONF_remote_cmd, cmd); conf_set_utf8(conf, CONF_remote_cmd, cmd);
sfree(cmd); sfree(cmd);
return; return;
} else { } else {