Skip to content

Commit

Permalink
Merge pull request #3459 from anastygnome/cp-fix
Browse files Browse the repository at this point in the history
cp: Do not dereference symlink even when dangling - fix issue #3364
  • Loading branch information
sylvestre authored May 3, 2022
2 parents 6747e72 + 70c451f commit 7c090af
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 4 deletions.
11 changes: 7 additions & 4 deletions src/uu/cp/src/cp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -992,7 +992,9 @@ fn copy_directory(
}

// if no-dereference is enabled and this is a symlink, copy it as a file
if !options.dereference && fs::symlink_metadata(root).unwrap().file_type().is_symlink() {
if !options.dereference && fs::symlink_metadata(root).unwrap().file_type().is_symlink()
// replace by is_symlink in rust>=1.58
{
return copy_file(root, target, options, symlinked_files);
}

Expand Down Expand Up @@ -1036,6 +1038,7 @@ fn copy_directory(
{
let p = or_continue!(path);
let is_symlink = fs::symlink_metadata(p.path())?.file_type().is_symlink();
// replace by is_symlink in rust >=1.58
let path = current_dir.join(&p.path());

let local_to_root_parent = match root_parent {
Expand Down Expand Up @@ -1288,7 +1291,7 @@ fn copy_file(

// Fail if dest is a dangling symlink or a symlink this program created previously
if fs::symlink_metadata(dest)
.map(|m| m.file_type().is_symlink())
.map(|m| m.file_type().is_symlink()) // replace by is_symlink in rust>=1.58
.unwrap_or(false)
{
if FileInformation::from_path(dest, false)
Expand All @@ -1301,7 +1304,7 @@ fn copy_file(
dest.display()
)));
}
if !dest.exists() {
if options.dereference && !dest.exists() {
return Err(Error::Error(format!(
"not writing through dangling symlink '{}'",
dest.display()
Expand Down Expand Up @@ -1535,7 +1538,7 @@ fn copy_link(
} else {
// we always need to remove the file to be able to create a symlink,
// even if it is writeable.
if dest.exists() {
if dest.is_file() {
fs::remove_file(dest)?;
}
dest.into()
Expand Down
12 changes: 12 additions & 0 deletions tests/by-util/test_cp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1506,6 +1506,18 @@ fn test_copy_through_dangling_symlink() {
.stderr_only("cp: not writing through dangling symlink 'target'");
}

#[test]
fn test_copy_through_dangling_symlink_no_dereference() {
let (at, mut ucmd) = at_and_ucmd!();
at.symlink_file("no-such-file", "dangle");
ucmd.arg("-P")
.arg("dangle")
.arg("d2")
.succeeds()
.no_stderr()
.no_stdout();
}

#[test]
#[cfg(unix)]
fn test_cp_archive_on_nonexistent_file() {
Expand Down

0 comments on commit 7c090af

Please sign in to comment.