util: Fix env load issues on Windows due to quoting (#50782)
Closes #47823 Before you mark this PR as ready for review, make sure that you have: - [x] Added a solid test coverage and/or screenshots from doing manual testing - [x] Done a self-review taking into account security and performance aspects - [x] No UI changes Release Notes: - Solves the issue where env variables failed to load when a project with dir path had `'`(single quote) in them, for example: `C:\Temp\O'Brien\project_1`. - added a zed pre-quote for directory paths and zed executable - handled pwsh, nushell, cmd, fish, posix, csh, tcsh, rc, xonsh, elvish based terminals - uses `try_quote` for quoting shell paths
This commit is contained in:
1 parent
df0b3de25f
commit
c091c90faf
2 files changed
+88
-42
No files matched your search
@@ -1012,4 +1012,40 @@ mod tests {
|
||||
"uname".to_string()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_try_quote_single_quote_paths() {
|
||||
let path_with_quote = r"C:\Temp\O'Brien\repo";
|
||||
let shlex_shells = [
|
||||
ShellKind::Posix,
|
||||
ShellKind::Fish,
|
||||
ShellKind::Csh,
|
||||
ShellKind::Tcsh,
|
||||
ShellKind::Rc,
|
||||
ShellKind::Xonsh,
|
||||
ShellKind::Elvish,
|
||||
ShellKind::Nushell,
|
||||
];
|
||||
|
||||
for shell_kind in shlex_shells {
|
||||
let quoted = shell_kind.try_quote(path_with_quote).unwrap().into_owned();
|
||||
assert_ne!(quoted, path_with_quote);
|
||||
assert_eq!(
|
||||
shlex::split("ed),
|
||||
Some(vec![path_with_quote.to_string()])
|
||||
);
|
||||
|
||||
if shell_kind == ShellKind::Nushell {
|
||||
let prefixed = shell_kind.prepend_command_prefix("ed);
|
||||
assert!(prefixed.starts_with('^'));
|
||||
}
|
||||
}
|
||||
|
||||
for shell_kind in [ShellKind::PowerShell, ShellKind::Pwsh] {
|
||||
let quoted = shell_kind.try_quote(path_with_quote).unwrap().into_owned();
|
||||
assert!(quoted.starts_with('\''));
|
||||
assert!(quoted.ends_with('\''));
|
||||
assert!(quoted.contains("O''Brien"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -141,6 +141,14 @@ async fn capture_windows(
|
||||
std::env::current_exe().context("Failed to determine current zed executable path.")?;
|
||||
|
||||
let shell_kind = ShellKind::new(shell_path, true);
|
||||
let directory_string = directory.display().to_string();
|
||||
let zed_path_string = zed_path.display().to_string();
|
||||
let quote_for_shell = |value: &str| {
|
||||
shell_kind
|
||||
.try_quote(value)
|
||||
.map(|quoted| quoted.into_owned())
|
||||
.unwrap_or_else(|| value.to_owned())
|
||||
};
|
||||
let mut cmd = crate::command::new_command(shell_path);
|
||||
cmd.args(args);
|
||||
let cmd = match shell_kind {
|
||||
@@ -149,52 +157,54 @@ async fn capture_windows(
|
||||
| ShellKind::Rc
|
||||
| ShellKind::Fish
|
||||
| ShellKind::Xonsh
|
||||
| ShellKind::Posix => cmd.args([
|
||||
"-l",
|
||||
"-i",
|
||||
"-c",
|
||||
&format!(
|
||||
"cd '{}'; '{}' --printenv",
|
||||
directory.display(),
|
||||
zed_path.display()
|
||||
),
|
||||
]),
|
||||
ShellKind::PowerShell | ShellKind::Pwsh => cmd.args([
|
||||
"-NonInteractive",
|
||||
"-NoProfile",
|
||||
"-Command",
|
||||
&format!(
|
||||
"Set-Location '{}'; & '{}' --printenv",
|
||||
directory.display(),
|
||||
zed_path.display()
|
||||
),
|
||||
]),
|
||||
ShellKind::Elvish => cmd.args([
|
||||
"-c",
|
||||
&format!(
|
||||
"cd '{}'; '{}' --printenv",
|
||||
directory.display(),
|
||||
zed_path.display()
|
||||
),
|
||||
]),
|
||||
ShellKind::Nushell => cmd.args([
|
||||
"-c",
|
||||
&format!(
|
||||
"cd '{}'; {}'{}' --printenv",
|
||||
directory.display(),
|
||||
shell_kind
|
||||
.command_prefix()
|
||||
.map(|prefix| prefix.to_string())
|
||||
.unwrap_or_default(),
|
||||
zed_path.display()
|
||||
),
|
||||
]),
|
||||
| ShellKind::Posix => {
|
||||
let quoted_directory = quote_for_shell(&directory_string);
|
||||
let quoted_zed_path = quote_for_shell(&zed_path_string);
|
||||
cmd.args([
|
||||
"-l",
|
||||
"-i",
|
||||
"-c",
|
||||
&format!("cd {}; {} --printenv", quoted_directory, quoted_zed_path),
|
||||
])
|
||||
}
|
||||
ShellKind::PowerShell | ShellKind::Pwsh => {
|
||||
let quoted_directory = ShellKind::quote_pwsh(&directory_string);
|
||||
let quoted_zed_path = ShellKind::quote_pwsh(&zed_path_string);
|
||||
cmd.args([
|
||||
"-NonInteractive",
|
||||
"-NoProfile",
|
||||
"-Command",
|
||||
&format!(
|
||||
"Set-Location {}; & {} --printenv",
|
||||
quoted_directory, quoted_zed_path
|
||||
),
|
||||
])
|
||||
}
|
||||
ShellKind::Elvish => {
|
||||
let quoted_directory = quote_for_shell(&directory_string);
|
||||
let quoted_zed_path = quote_for_shell(&zed_path_string);
|
||||
cmd.args([
|
||||
"-c",
|
||||
&format!("cd {}; {} --printenv", quoted_directory, quoted_zed_path),
|
||||
])
|
||||
}
|
||||
ShellKind::Nushell => {
|
||||
let quoted_directory = quote_for_shell(&directory_string);
|
||||
let quoted_zed_path = quote_for_shell(&zed_path_string);
|
||||
let zed_command = shell_kind
|
||||
.prepend_command_prefix("ed_zed_path)
|
||||
.into_owned();
|
||||
cmd.args([
|
||||
"-c",
|
||||
&format!("cd {}; {} --printenv", quoted_directory, zed_command),
|
||||
])
|
||||
}
|
||||
ShellKind::Cmd => cmd.args([
|
||||
"/c",
|
||||
"cd",
|
||||
&directory.display().to_string(),
|
||||
&directory_string,
|
||||
"&&",
|
||||
&zed_path.display().to_string(),
|
||||
&zed_path_string,
|
||||
"--printenv",
|
||||
]),
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user