diff --git a/src/uu/rm/src/rm.rs b/src/uu/rm/src/rm.rs index a20a57d7f36..0443bc51f62 100644 --- a/src/uu/rm/src/rm.rs +++ b/src/uu/rm/src/rm.rs @@ -851,7 +851,9 @@ fn path_is_current_or_parent_directory(path: &Path) -> bool { let dir_separator = MAIN_SEPARATOR as u8; if let Ok(path_bytes) = path_str { return path_bytes == ([b'.']) + || path_bytes == ([b'.', dir_separator]) || path_bytes == ([b'.', b'.']) + || path_bytes == ([b'.', b'.', dir_separator]) || path_bytes.ends_with(&[dir_separator, b'.']) || path_bytes.ends_with(&[dir_separator, b'.', b'.']) || path_bytes.ends_with(&[dir_separator, b'.', dir_separator]) diff --git a/src/uucore/src/lib/features/backup_control.rs b/src/uucore/src/lib/features/backup_control.rs index ed6b6703441..bf13b12988c 100644 --- a/src/uucore/src/lib/features/backup_control.rs +++ b/src/uucore/src/lib/features/backup_control.rs @@ -602,6 +602,7 @@ mod tests { let result = determine_backup_mode(&matches).unwrap(); assert_eq!(result, BackupMode::Numbered); + // cleaning up because this can affect tests that rely on env state unsafe { env::remove_var(ENV_VERSION_CONTROL) }; } @@ -615,6 +616,7 @@ mod tests { let result = determine_backup_mode(&matches).unwrap(); assert_eq!(result, BackupMode::None); + // cleaning up because this can affect tests that rely on env state unsafe { env::remove_var(ENV_VERSION_CONTROL) }; } @@ -630,6 +632,7 @@ mod tests { assert!(result.is_err()); let text = format!("{}", result.unwrap_err()); assert!(text.contains("invalid argument 'foobar' for '$VERSION_CONTROL'")); + // cleaning up because this can affect tests that rely on env state unsafe { env::remove_var(ENV_VERSION_CONTROL) }; } @@ -645,6 +648,7 @@ mod tests { assert!(result.is_err()); let text = format!("{}", result.unwrap_err()); assert!(text.contains("ambiguous argument 'n' for '$VERSION_CONTROL'")); + // cleaning up because this can affect tests that rely on env state unsafe { env::remove_var(ENV_VERSION_CONTROL) }; } @@ -658,6 +662,7 @@ mod tests { let result = determine_backup_mode(&matches).unwrap(); assert_eq!(result, BackupMode::Simple); + // cleaning up because this can affect tests that rely on env state unsafe { env::remove_var(ENV_VERSION_CONTROL) }; } @@ -682,6 +687,8 @@ mod tests { let result = determine_backup_mode(&matches).unwrap(); assert_eq!(result, BackupMode::Numbered); + // cleaning up because this can affect tests that rely on env state + unsafe { env::remove_var(ENV_VERSION_CONTROL) }; } #[test] diff --git a/tests/by-util/test_rm.rs b/tests/by-util/test_rm.rs index 38230f2ad36..ad52fc35a7f 100644 --- a/tests/by-util/test_rm.rs +++ b/tests/by-util/test_rm.rs @@ -767,12 +767,22 @@ fn test_current_or_parent_dir_rm4() { at.mkdir("d"); + let file_1 = "file1"; + let file_2 = "d/file2"; + + at.touch(file_1); + at.touch(file_2); + let answers = [ "rm: refusing to remove '.' or '..' directory: skipping 'd/.'", "rm: refusing to remove '.' or '..' directory: skipping 'd/./'", "rm: refusing to remove '.' or '..' directory: skipping 'd/./'", "rm: refusing to remove '.' or '..' directory: skipping 'd/..'", "rm: refusing to remove '.' or '..' directory: skipping 'd/../'", + "rm: refusing to remove '.' or '..' directory: skipping '.'", + "rm: refusing to remove '.' or '..' directory: skipping './'", + "rm: refusing to remove '.' or '..' directory: skipping '../'", + "rm: refusing to remove '.' or '..' directory: skipping '..'", ]; let std_err_str = ts .ucmd() @@ -782,12 +792,20 @@ fn test_current_or_parent_dir_rm4() { .arg("d/.////") .arg("d/..") .arg("d/../") + .arg(".") + .arg("./") + .arg("../") + .arg("..") .fails() .stderr_move_str(); for (idx, line) in std_err_str.lines().enumerate() { assert_eq!(line, answers[idx]); } + // checks that no file was silently removed + assert!(at.dir_exists("d")); + assert!(at.file_exists(file_1)); + assert!(at.file_exists(file_2)); } #[test] @@ -798,12 +816,22 @@ fn test_current_or_parent_dir_rm4_windows() { at.mkdir("d"); + let file_1 = "file1"; + let file_2 = "d/file2"; + + at.touch(file_1); + at.touch(file_2); + let answers = [ "rm: refusing to remove '.' or '..' directory: skipping 'd\\.'", "rm: refusing to remove '.' or '..' directory: skipping 'd\\.\\'", "rm: refusing to remove '.' or '..' directory: skipping 'd\\.\\'", "rm: refusing to remove '.' or '..' directory: skipping 'd\\..'", "rm: refusing to remove '.' or '..' directory: skipping 'd\\..\\'", + "rm: refusing to remove '.' or '..' directory: skipping '.'", + "rm: refusing to remove '.' or '..' directory: skipping '.\\'", + "rm: refusing to remove '.' or '..' directory: skipping '..'", + "rm: refusing to remove '.' or '..' directory: skipping '..\\'", ]; let std_err_str = ts .ucmd() @@ -813,12 +841,21 @@ fn test_current_or_parent_dir_rm4_windows() { .arg("d\\.\\\\\\\\") .arg("d\\..") .arg("d\\..\\") + .arg(".") + .arg(".\\") + .arg("..") + .arg("..\\") .fails() .stderr_move_str(); for (idx, line) in std_err_str.lines().enumerate() { assert_eq!(line, answers[idx]); } + + // checks that no file was silently removed + assert!(at.dir_exists("d")); + assert!(at.file_exists(file_1)); + assert!(at.file_exists(file_2)); } #[test]