fix escaping for commands with spaces, and newline boundary issue

This commit is contained in:
iceweasel-oai
2026-03-23 15:47:13 -07:00
parent 5044e826ab
commit 3a95229ee9
2 changed files with 44 additions and 7 deletions

View File

@@ -177,19 +177,18 @@ fn spawn_output_reader(
})
}
fn normalize_windows_tty_input(bytes: &[u8]) -> Vec<u8> {
fn normalize_windows_tty_input(bytes: &[u8], previous_was_cr: &mut bool) -> Vec<u8> {
let mut normalized = Vec::with_capacity(bytes.len());
let mut previous_was_cr = false;
for &byte in bytes {
if byte == b'\n' {
if !previous_was_cr {
if !*previous_was_cr {
normalized.push(b'\r');
}
normalized.push(b'\n');
previous_was_cr = false;
*previous_was_cr = false;
} else {
normalized.push(byte);
previous_was_cr = byte == b'\r';
*previous_was_cr = byte == b'\r';
}
}
normalized
@@ -202,12 +201,13 @@ fn spawn_input_writer(
normalize_newlines: bool,
) -> tokio::task::JoinHandle<()> {
tokio::task::spawn_blocking(move || {
let mut previous_was_cr = false;
while let Some(bytes) = writer_rx.blocking_recv() {
let Some(handle) = input_write else {
continue;
};
let bytes = if normalize_newlines {
normalize_windows_tty_input(&bytes)
normalize_windows_tty_input(&bytes, &mut previous_was_cr)
} else {
bytes
};

View File

@@ -88,7 +88,29 @@ pub fn argv_to_command_line(argv: &[String]) -> String {
if args.is_empty() {
return quote_windows_arg(program);
}
return format!("{} {}", quote_windows_arg(program), args.join(" "));
let cmd_switch_index = args
.iter()
.position(|arg| arg.eq_ignore_ascii_case("/c") || arg.eq_ignore_ascii_case("/k"));
let rendered_args = if let Some(index) = cmd_switch_index {
let mut rendered = args[..=index]
.iter()
.map(|arg| quote_windows_arg(arg))
.collect::<Vec<_>>();
let suffix = &args[index + 1..];
if suffix.len() == 1 {
rendered.push(suffix[0].clone());
} else {
rendered.extend(suffix.iter().map(|arg| quote_windows_arg(arg)));
}
rendered.join(" ")
} else {
args.iter()
.map(|arg| quote_windows_arg(arg))
.collect::<Vec<_>>()
.join(" ")
};
return format!("{} {rendered_args}", quote_windows_arg(program));
}
argv.iter()
@@ -179,6 +201,21 @@ mod tests {
"pwsh.exe -Command \"Write-Output \\\"hello world\\\"\""
);
}
#[test]
fn argv_to_command_line_quotes_cmd_suffix_tokens_with_spaces() {
let argv = vec![
"cmd.exe".to_string(),
"/c".to_string(),
"type".to_string(),
"C:\\Program Files\\a.txt".to_string(),
];
assert_eq!(
argv_to_command_line(&argv),
"cmd.exe /c type \"C:\\Program Files\\a.txt\""
);
}
}
const SID_ADMINISTRATORS: &str = "S-1-5-32-544";