Use externally sourced shell-escape

Closes #3374
This commit is contained in:
Steven Fackler 2016-12-30 10:21:10 -08:00
parent 740f9c0c97
commit d105e75271
7 changed files with 11 additions and 119 deletions

1
.gitignore vendored
View File

@ -10,3 +10,4 @@ src/registry/Cargo.lock
rustc
__pycache__
.idea/
*.iml

7
Cargo.lock generated
View File

@ -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"

View File

@ -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"

View File

@ -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;

View File

@ -39,7 +39,6 @@ mod cfg;
mod dependency_queue;
mod rustc;
mod sha256;
mod shell_escape;
mod vcs;
mod lazy_cell;
mod flock;

View File

@ -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 {

View File

@ -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 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<str>) -> Cow<str> {
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<str>) -> Cow<str> {
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<str>) -> Cow<str> {
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\ "#);
}
}