From 811ddd3eeb4c69f83d4fa7979006e89b4fd03591 Mon Sep 17 00:00:00 2001 From: WindSoilder Date: Thu, 1 Feb 2024 09:06:03 +0800 Subject: [PATCH] cp: expand target path before checking (#11692) # Description Fixes: #11683 # User-Facing Changes NaN # Tests + Formatting ~~I don't think we need to add a test, or else it'll copy some file to user's directory, it seems bad.~~ Done. # After Submitting NaN --- crates/nu-command/src/filesystem/ucp.rs | 5 ++--- crates/nu-command/tests/commands/ucp.rs | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/crates/nu-command/src/filesystem/ucp.rs b/crates/nu-command/src/filesystem/ucp.rs index d3e6dcf23e824..202957dbdad60 100644 --- a/crates/nu-command/src/filesystem/ucp.rs +++ b/crates/nu-command/src/filesystem/ucp.rs @@ -172,6 +172,8 @@ impl Command for UCp { let target_path = PathBuf::from(&nu_utils::strip_ansi_string_unlikely( target.item.to_string(), )); + let cwd = current_dir(engine_state, stack)?; + let target_path = nu_path::expand_path_with(&target_path, &cwd); if target.item.as_ref().ends_with(PATH_SEPARATOR) && !target_path.is_dir() { return Err(ShellError::GenericError { error: "is not a directory".into(), @@ -184,7 +186,6 @@ impl Command for UCp { // paths now contains the sources - let cwd = current_dir(engine_state, stack)?; let mut sources: Vec = Vec::new(); for mut p in paths { @@ -227,8 +228,6 @@ impl Command for UCp { } } - let target_path = nu_path::expand_path_with(&target_path, &cwd); - let attributes = make_attributes(preserve)?; let options = uu_cp::Options { diff --git a/crates/nu-command/tests/commands/ucp.rs b/crates/nu-command/tests/commands/ucp.rs index 1d94e72958e60..09569ff7512a4 100644 --- a/crates/nu-command/tests/commands/ucp.rs +++ b/crates/nu-command/tests/commands/ucp.rs @@ -1122,3 +1122,19 @@ fn test_cp_inside_glob_metachars_dir() { assert!(files_exist_at(vec!["test_file.txt"], dirs.test())); }); } + +#[cfg(not(windows))] +#[test] +fn test_cp_to_customized_home_directory() { + Playground::setup("cp_to_home", |dirs, sandbox| { + std::env::set_var("HOME", dirs.test()); + sandbox.with_files(vec![EmptyFile("test_file.txt")]); + let actual = nu!(cwd: dirs.test(), "mkdir test; cp test_file.txt ~/test/"); + + assert!(actual.err.is_empty()); + assert!(files_exist_at( + vec!["test_file.txt"], + dirs.test().join("test") + )); + }) +}