Restrict Nu with a cleaned environment. (#1222)

This commit is contained in:
Andrés N. Robalino 2020-01-13 23:17:20 -05:00 committed by GitHub
parent 98028433ad
commit 78a644da2b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 45 additions and 85 deletions

View File

@ -226,10 +226,12 @@ pub fn executable_path() -> PathBuf {
} }
pub fn binaries() -> PathBuf { pub fn binaries() -> PathBuf {
let mut path = PathBuf::new(); PathBuf::from(env!("CARGO_MANIFEST_DIR"))
path.push("target"); .parent()
path.push("debug"); .expect("Couldn't find the debug binaries directory")
path .parent()
.expect("Couldn't find the debug binaries directory")
.join("target/debug")
} }
pub fn in_directory(str: impl AsRef<Path>) -> String { pub fn in_directory(str: impl AsRef<Path>) -> String {

View File

@ -28,7 +28,18 @@ macro_rules! nu {
$crate::fs::DisplayPath::display_path(&$path) $crate::fs::DisplayPath::display_path(&$path)
); );
let dummies = $crate::fs::binaries();
let dummies = dunce::canonicalize(&dummies).unwrap_or_else(|e| {
panic!(
"Couldn't canonicalize dummy binaries path {}: {:?}",
dummies.display(),
e
)
});
let mut process = match Command::new($crate::fs::executable_path()) let mut process = match Command::new($crate::fs::executable_path())
.env_clear()
.env("PATH", dummies)
.stdin(Stdio::piped()) .stdin(Stdio::piped())
.stdout(Stdio::piped()) .stdout(Stdio::piped())
.spawn() .spawn()
@ -85,7 +96,18 @@ macro_rules! nu_error {
$crate::fs::DisplayPath::display_path(&$path) $crate::fs::DisplayPath::display_path(&$path)
); );
let dummies = $crate::fs::binaries();
let dummies = dunce::canonicalize(&dummies).unwrap_or_else(|e| {
panic!(
"Couldn't canonicalize dummy binaries path {}: {:?}",
dummies.display(),
e
)
});
let mut process = Command::new($crate::fs::executable_path()) let mut process = Command::new($crate::fs::executable_path())
.env_clear()
.env("PATH", dummies)
.stdout(Stdio::piped()) .stdout(Stdio::piped())
.stdin(Stdio::piped()) .stdin(Stdio::piped())
.stderr(Stdio::piped()) .stderr(Stdio::piped())

View File

@ -1,102 +1,38 @@
mod pipeline { mod pipeline {
use nu_test_support::fs::Stub::EmptyFile; use nu_test_support::{nu, nu_error};
use nu_test_support::playground::Playground;
use nu_test_support::{nu, nu_error, pipeline};
#[test] #[test]
fn can_process_row_as_it_argument_to_an_external_command_given_the_it_data_is_a_string() { fn doesnt_break_on_utf8() {
Playground::setup("it_argument_test_1", |dirs, sandbox| { let actual = nu!(cwd: ".", "echo ö");
sandbox.with_files(vec![
EmptyFile("jonathan_likes_cake.txt"),
EmptyFile("andres_likes_arepas.txt"),
]);
let actual = nu!( assert_eq!(actual, "ö", "'{}' should contain ö", actual);
cwd: dirs.test(), pipeline(
r#"
ls
| sort-by name
| get name
| ^echo $it
"#
));
#[cfg(windows)]
assert_eq!(actual, "andres_likes_arepas.txt jonathan_likes_cake.txt");
#[cfg(not(windows))]
assert_eq!(actual, "andres_likes_arepas.txtjonathan_likes_cake.txt");
})
}
#[test]
fn doesnt_break_on_utf8_command() {
let actual = nu!(
cwd: ".", pipeline(
r#"
echo ö
"#
));
assert!(
actual.contains("ö"),
format!("'{}' should contain ö", actual)
);
}
#[test]
fn can_process_row_as_it_argument_to_an_external_command_given_the_it_data_is_one_string_line()
{
Playground::setup("it_argument_test_2", |dirs, sandbox| {
sandbox.with_files(vec![
EmptyFile("jonathan_likes_cake.txt"),
EmptyFile("andres_likes_arepas.txt"),
]);
let actual = nu!(
cwd: dirs.test(), pipeline(
r#"
ls
| sort-by name
| get name
| lines
| ^echo $it
"#
));
#[cfg(windows)]
assert_eq!(actual, "andres_likes_arepas.txt jonathan_likes_cake.txt");
#[cfg(not(windows))]
assert_eq!(actual, "andres_likes_arepas.txtjonathan_likes_cake.txt");
})
} }
#[test] #[test]
fn can_process_stdout_of_external_piped_to_stdin_of_external() { fn can_process_stdout_of_external_piped_to_stdin_of_external() {
let actual = nu!( let actual = nu!(
cwd: "tests/fixtures", cwd: ".",
"^echo 1 | ^cat" r#"cococo "nushelll" | chop"#
); );
assert!(actual.contains("1")); assert_eq!(actual, "nushell");
} }
#[test] #[test]
fn can_process_row_from_internal_piped_to_stdin_of_external() { fn can_process_one_row_from_internal_piped_to_stdin_of_external() {
let actual = nu!( let actual = nu!(
cwd: "tests/fixtures", cwd: ".",
"echo \"1\" | ^cat" r#"echo "nushelll" | chop"#
); );
assert!(actual.contains("1")); assert_eq!(actual, "nushell");
} }
#[test] #[test]
fn shows_error_for_external_command_that_fails() { fn shows_error_for_external_command_that_fails() {
let actual = nu_error!( let actual = nu_error!(
cwd: "tests/fixtures", cwd: ".",
"^false" "fail"
); );
assert!(actual.contains("External command failed")); assert!(actual.contains("External command failed"));
@ -108,9 +44,9 @@ mod pipeline {
#[test] #[test]
fn as_home_directory_when_passed_as_argument_and_begins_with_tilde_to_an_external() { fn as_home_directory_when_passed_as_argument_and_begins_with_tilde_to_an_external() {
let actual = nu!( let actual = nu!(
cwd: std::path::PathBuf::from("."), cwd: ".",
r#" r#"
sh -c "echo ~" cococo ~
"# "#
); );
@ -123,9 +59,9 @@ mod pipeline {
#[test] #[test]
fn does_not_expand_when_passed_as_argument_and_does_not_start_with_tilde_to_an_external() { fn does_not_expand_when_passed_as_argument_and_does_not_start_with_tilde_to_an_external() {
let actual = nu!( let actual = nu!(
cwd: std::path::PathBuf::from("."), cwd: ".",
r#" r#"
sh -c "echo 1~1" cococo "1~1"
"# "#
); );