Skip to content

Commit 0ec36be

Browse files
authored
Merge pull request #7838 from zcg00/install_deletes_files
install: fixes issue #7795
2 parents 6327282 + 827d0fc commit 0ec36be

File tree

2 files changed

+39
-0
lines changed

2 files changed

+39
-0
lines changed

src/uu/install/src/install.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ enum InstallError {
101101

102102
#[error("cannot overwrite directory {} with non-directory {}", .0.quote(), .1.quote())]
103103
OverrideDirectoryFailed(PathBuf, PathBuf),
104+
105+
#[error("'{0}' and '{1}' are the same file")]
106+
SameFile(PathBuf, PathBuf),
104107
}
105108

106109
impl UError for InstallError {
@@ -751,6 +754,12 @@ fn copy_normal_file(from: &Path, to: &Path) -> UResult<()> {
751754
/// Returns an empty Result or an error in case of failure.
752755
///
753756
fn copy_file(from: &Path, to: &Path) -> UResult<()> {
757+
if let Ok(to_abs) = to.canonicalize() {
758+
if from.canonicalize()? == to_abs {
759+
return Err(InstallError::SameFile(from.to_path_buf(), to.to_path_buf()).into());
760+
}
761+
}
762+
754763
if to.is_dir() && !from.is_dir() {
755764
return Err(InstallError::OverrideDirectoryFailed(
756765
to.to_path_buf().clone(),

tests/by-util/test_install.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1778,3 +1778,33 @@ fn test_install_failing_copy_file_to_target_contain_subdir_with_same_name() {
17781778
.fails()
17791779
.stderr_contains("cannot overwrite directory");
17801780
}
1781+
1782+
#[test]
1783+
fn test_install_same_file() {
1784+
let (at, mut ucmd) = at_and_ucmd!();
1785+
let file = "file";
1786+
1787+
at.touch(file);
1788+
ucmd.arg(file)
1789+
.arg(".")
1790+
.fails()
1791+
.stderr_contains("'file' and './file' are the same file");
1792+
}
1793+
1794+
#[test]
1795+
fn test_install_symlink_same_file() {
1796+
let (at, mut ucmd) = at_and_ucmd!();
1797+
let file = "file";
1798+
let target_dir = "target_dir";
1799+
let target_link = "target_link";
1800+
1801+
at.mkdir(target_dir);
1802+
at.touch(format!("{target_dir}/{file}"));
1803+
at.symlink_file(target_dir, target_link);
1804+
ucmd.arg(format!("{target_dir}/{file}"))
1805+
.arg(target_link)
1806+
.fails()
1807+
.stderr_contains(format!(
1808+
"'{target_dir}/{file}' and '{target_link}/{file}' are the same file"
1809+
));
1810+
}

0 commit comments

Comments
 (0)