Harden Windows SSH config quoting
ci / test (push) Canceled after 0s
ci / fuzz-smoke (push) Canceled after 0s
ci / windows-client (push) Canceled after 0s
ci / package-release (linux-x86_64, ubuntu-latest, , , ) (push) Canceled after 0s
ci / package-release (macos-aarch64, macos-14, , , ) (push) Canceled after 0s
ci / package-release (macos-x86_64, macos-13, , , ) (push) Canceled after 0s
ci / package-release (windows-aarch64, windows-latest, aarch64, windows, aarch64-pc-windows-msvc) (push) Canceled after 0s
ci / package-release (windows-x86_64, windows-latest, , , ) (push) Canceled after 0s
ci / remote-bench (push) Canceled after 0s
ci / publish-gitea-release (push) Canceled after 0s
ci / test (push) Canceled after 0s
ci / fuzz-smoke (push) Canceled after 0s
ci / windows-client (push) Canceled after 0s
ci / package-release (linux-x86_64, ubuntu-latest, , , ) (push) Canceled after 0s
ci / package-release (macos-aarch64, macos-14, , , ) (push) Canceled after 0s
ci / package-release (macos-x86_64, macos-13, , , ) (push) Canceled after 0s
ci / package-release (windows-aarch64, windows-latest, aarch64, windows, aarch64-pc-windows-msvc) (push) Canceled after 0s
ci / package-release (windows-x86_64, windows-latest, , , ) (push) Canceled after 0s
ci / remote-bench (push) Canceled after 0s
ci / publish-gitea-release (push) Canceled after 0s
This commit is contained in:
+67
-8
@@ -4711,13 +4711,46 @@ fn shell_word(value: &str) -> String {
|
||||
}
|
||||
|
||||
fn ssh_config_word(value: &str) -> String {
|
||||
if cfg!(windows) {
|
||||
format!("\"{}\"", value.replace('"', "\\\""))
|
||||
ssh_config_word_for_os(std::env::consts::OS, value)
|
||||
}
|
||||
|
||||
fn ssh_config_word_for_os(os: &str, value: &str) -> String {
|
||||
if os == "windows" {
|
||||
windows_command_word(value)
|
||||
} else {
|
||||
shell_word(value)
|
||||
}
|
||||
}
|
||||
|
||||
fn windows_command_word(value: &str) -> String {
|
||||
let mut out = String::from("\"");
|
||||
let mut backslashes = 0usize;
|
||||
for ch in value.chars() {
|
||||
if ch == '\\' {
|
||||
backslashes += 1;
|
||||
continue;
|
||||
}
|
||||
if ch == '"' {
|
||||
for _ in 0..(backslashes * 2 + 1) {
|
||||
out.push('\\');
|
||||
}
|
||||
out.push('"');
|
||||
backslashes = 0;
|
||||
continue;
|
||||
}
|
||||
for _ in 0..backslashes {
|
||||
out.push('\\');
|
||||
}
|
||||
backslashes = 0;
|
||||
out.push(ch);
|
||||
}
|
||||
for _ in 0..(backslashes * 2) {
|
||||
out.push('\\');
|
||||
}
|
||||
out.push('"');
|
||||
out
|
||||
}
|
||||
|
||||
fn local_bootstrap(
|
||||
session: &str,
|
||||
mode: &str,
|
||||
@@ -10135,12 +10168,13 @@ mod tests {
|
||||
should_hold_post_submit_input, should_reconnect_before_input_for_local_sleep,
|
||||
should_repaint_idle_terminal, should_strip_unowned_terminal_reports,
|
||||
split_after_command_submit, split_trace_tokens, ssh_command_target, ssh_config_uses_proxy,
|
||||
ssh_destination_host, ssh_username, ssh_with_user, startup_command, status_ssh_target,
|
||||
strip_stale_mouse_reports, strip_terminal_focus_reports, strip_unowned_terminal_reports,
|
||||
summarize_trace_file, summarize_trace_file_with_mode, terminal_private_mode_transition,
|
||||
toml_bare_key_or_quoted, top_trace_events, trace_report_warnings, unix_update_script,
|
||||
update_binary_version_for_installer, update_installer_url, update_version_status,
|
||||
upsert_managed_block, valid_forward_host, vscode_safe_alias, wake_repaint_retry_deadline,
|
||||
ssh_config_word_for_os, ssh_destination_host, ssh_username, ssh_with_user, startup_command,
|
||||
status_ssh_target, strip_stale_mouse_reports, strip_terminal_focus_reports,
|
||||
strip_unowned_terminal_reports, summarize_trace_file, summarize_trace_file_with_mode,
|
||||
terminal_private_mode_transition, toml_bare_key_or_quoted, top_trace_events,
|
||||
trace_report_warnings, unix_update_script, update_binary_version_for_installer,
|
||||
update_installer_url, update_version_status, upsert_managed_block, valid_forward_host,
|
||||
vscode_safe_alias, wake_repaint_retry_deadline, windows_command_word,
|
||||
windows_mode_from_readonly, windows_readonly_from_mode, windows_update_script,
|
||||
};
|
||||
use dosh::config::{ClientConfig, CommandExtension, HostConfig};
|
||||
@@ -10503,6 +10537,31 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ssh_config_word_quotes_for_unix_and_windows() {
|
||||
assert_eq!(
|
||||
ssh_config_word_for_os("linux", "/Users/palav/My App/dosh"),
|
||||
"'/Users/palav/My App/dosh'"
|
||||
);
|
||||
assert_eq!(
|
||||
ssh_config_word_for_os("windows", r#"C:\Users\palav\My App\dosh.exe"#),
|
||||
r#""C:\Users\palav\My App\dosh.exe""#
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn windows_command_word_escapes_quotes_and_trailing_backslashes() {
|
||||
assert_eq!(
|
||||
windows_command_word(r#"C:\Program Files\dosh\"#),
|
||||
r#""C:\Program Files\dosh\\""#
|
||||
);
|
||||
assert_eq!(windows_command_word(r#"say "hi""#), r#""say \"hi\"""#);
|
||||
assert_eq!(
|
||||
windows_command_word(r#"C:\path\before"quote"#),
|
||||
r#""C:\path\before\"quote""#
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parses_ssh_config_native_parity_options() {
|
||||
let parsed = parse_ssh_config(
|
||||
|
||||
Reference in New Issue
Block a user