From 3b18a3e9c264c39e426fd35a4494407b0b2002d1 Mon Sep 17 00:00:00 2001 From: Arlo Siemsen Date: Tue, 9 Mar 2021 10:22:29 -0800 Subject: [PATCH] Parse credential.helper command line using shell-words. Since `sh` is not available by default on Windows, git2-rs currently splits the credential helper string by whitespace, which attempts to execute an invalid command line in the case of the default credential helper on Windows. The default git credential helper on Windows (Git Credential Manager Core) is set up as `C:/Program\ Files\ \(x86\)/Git\ Credential\ Manager\ Core/git-credential-manager-core.exe` This change resolves the issue by parsing the command line using `shell_words`, which follows the unix-style parsing rules used by sh. `shell-words` is a small crate that does not have any additional dependencies. --- Cargo.toml | 1 + src/cred.rs | 14 +++++++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 4135894104..e7325291f6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ url = "2.0" bitflags = "1.1.0" libc = "0.2" log = "0.4.8" +shell-words = "1.0" libgit2-sys = { path = "libgit2-sys", version = "0.12.18" } [target."cfg(all(unix, not(target_os = \"macos\")))".dependencies] diff --git a/src/cred.rs b/src/cred.rs index a47cddba60..54cbc82373 100644 --- a/src/cred.rs +++ b/src/cred.rs @@ -380,12 +380,16 @@ impl CredentialHelper { Ok(p) => p, Err(e) => { debug!("`sh` failed to spawn: {}", e); - let mut parts = cmd.split_whitespace(); + let mut parts = match shell_words::split(cmd) { + Ok(parts) => parts.into_iter(), + Err(e) => { + debug!("command {:?} parsing failed with {}", cmd, e); + return (None, None); + } + }; let mut c = Command::new(parts.next().unwrap()); - for arg in parts { - c.arg(arg); - } - c.arg("get") + c.args(parts) + .arg("get") .stdin(Stdio::piped()) .stdout(Stdio::piped()) .stderr(Stdio::piped());