diff --git a/.gitignore b/.gitignore index 8a6bfeba36d..e0d63ba2e18 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ src/registry/Cargo.lock rustc __pycache__ .idea/ +*.iml \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index 3e5469e4c85..d9575530561 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -28,6 +28,7 @@ dependencies = [ "regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.21 (registry+https://github.com/rust-lang/crates.io-index)", "semver 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "shell-escape 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "tar 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)", "tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -513,6 +514,11 @@ dependencies = [ "regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "shell-escape" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "strsim" version = "0.5.1" @@ -677,6 +683,7 @@ dependencies = [ "checksum rustc-serialize 0.3.21 (registry+https://github.com/rust-lang/crates.io-index)" = "bff9fc1c79f2dec76b253273d07682e94a978bd8f132ded071188122b2af9818" "checksum semver 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ae2ff60ecdb19c255841c066cbfa5f8c2a4ada1eb3ae47c77ab6667128da71f5" "checksum semver-parser 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e88e43a5a74dd2a11707f9c21dfd4a423c66bd871df813227bb0a3e78f3a1ae9" +"checksum shell-escape 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f155750265e04a1d42cc4bba7dbcadf7ca055b11f8c1e01884a40fc7d91a8431" "checksum strsim 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "50c069df92e4b01425a8bf3576d5d417943a6a7272fbabaf5bd80b1aaa76442e" "checksum tar 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "0c9048e27119ff1fcf5b0e147ca0936d911b607d87440b042d4ecaa111b523ee" "checksum tempdir 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "87974a6f5c1dfb344d733055601650059a3363de2a6104819293baff662132d6" diff --git a/Cargo.toml b/Cargo.toml index 8e1ee276515..a04994dac1c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,6 +39,7 @@ psapi-sys = "0.1" regex = "0.1" rustc-serialize = "0.3" semver = "0.5.0" +shell-escape = "0.1" tar = { version = "0.4", default-features = false } tempdir = "0.3" term = "0.4.4" diff --git a/src/cargo/lib.rs b/src/cargo/lib.rs index 33098ee1749..46daa9441e7 100644 --- a/src/cargo/lib.rs +++ b/src/cargo/lib.rs @@ -18,6 +18,7 @@ extern crate num_cpus; extern crate regex; extern crate rustc_serialize; extern crate semver; +extern crate shell_escape; extern crate tar; extern crate tempdir; extern crate term; diff --git a/src/cargo/util/mod.rs b/src/cargo/util/mod.rs index 56bbeed0d99..d1195d75cf8 100644 --- a/src/cargo/util/mod.rs +++ b/src/cargo/util/mod.rs @@ -39,7 +39,6 @@ mod cfg; mod dependency_queue; mod rustc; mod sha256; -mod shell_escape; mod vcs; mod lazy_cell; mod flock; diff --git a/src/cargo/util/process_builder.rs b/src/cargo/util/process_builder.rs index ed92321896e..26f872ed459 100644 --- a/src/cargo/util/process_builder.rs +++ b/src/cargo/util/process_builder.rs @@ -6,7 +6,7 @@ use std::path::Path; use std::process::{Command, Stdio, Output}; use util::{CargoResult, ProcessError, process_error, read2}; -use util::shell_escape::escape; +use shell_escape::escape; #[derive(Clone, PartialEq, Debug)] pub struct ProcessBuilder { diff --git a/src/cargo/util/shell_escape.rs b/src/cargo/util/shell_escape.rs deleted file mode 100644 index 2220017064d..00000000000 --- a/src/cargo/util/shell_escape.rs +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::borrow::Cow; -use std::env; - -pub fn escape(s: Cow) -> Cow { - if cfg!(unix) || env::var("MSYSTEM").is_ok() { - unix::escape(s) - } else { - windows::escape(s) - } -} - -pub mod windows { - use std::borrow::Cow; - use std::iter::repeat; - - /// Escape for the windows cmd.exe shell, for more info see this url: - /// - /// http://blogs.msdn.com/b/twistylittlepassagesallalike/archive/2011/04/23 - /// /everyone-quotes-arguments-the-wrong-way.aspx - pub fn escape(s: Cow) -> Cow { - let mut needs_escape = false; - for ch in s.chars() { - match ch { - '"' | '\t' | '\n' | ' ' => needs_escape = true, - _ => {} - } - } - if !needs_escape { - return s - } - let mut es = String::with_capacity(s.len()); - es.push('"'); - let mut chars = s.chars().peekable(); - loop { - let mut nslashes = 0; - while let Some(&'\\') = chars.peek() { - chars.next(); - nslashes += 1; - } - - match chars.next() { - Some('"') => { - es.extend(repeat('\\').take(nslashes * 2 + 1)); - es.push('"'); - } - Some(c) => { - es.extend(repeat('\\').take(nslashes)); - es.push(c); - } - None => { - es.extend(repeat('\\').take(nslashes * 2)); - break; - } - } - - } - es.push('"'); - es.into() - } - - #[test] - fn test_escape() { - assert_eq!(escape("--aaa=bbb-ccc".into()), "--aaa=bbb-ccc"); - assert_eq!(escape("linker=gcc -L/foo -Wl,bar".into()), - r#""linker=gcc -L/foo -Wl,bar""#); - assert_eq!(escape(r#"--features="default""#.into()), - r#""--features=\"default\"""#); - assert_eq!(escape(r#"\path\to\my documents\"#.into()), - r#""\path\to\my documents\\""#); - } -} - -pub mod unix { - use std::borrow::Cow; - - const SHELL_SPECIAL: &'static str = r#" \$'"`!"#; - - /// Escape characters that may have special meaning in a shell, - /// including spaces. - pub fn escape(s: Cow) -> Cow { - let escape_char = '\\'; - // check if string needs to be escaped - let clean = SHELL_SPECIAL.chars().all(|sp_char| !s.contains(sp_char)); - if clean { - return s - } - let mut es = String::with_capacity(s.len()); - for ch in s.chars() { - if SHELL_SPECIAL.contains(ch) { - es.push(escape_char); - } - es.push(ch) - } - es.into() - } - - #[test] - fn test_escape() { - assert_eq!(escape("--aaa=bbb-ccc".into()), "--aaa=bbb-ccc"); - assert_eq!(escape("linker=gcc -L/foo -Wl,bar".into()), - r#"linker=gcc\ -L/foo\ -Wl,bar"#); - assert_eq!(escape(r#"--features="default""#.into()), - r#"--features=\"default\""#); - assert_eq!(escape(r#"'!\$`\\\n "#.into()), - r#"\'\!\\\$\`\\\\\\n\ "#); - } -}