diff --git a/src/uu/mv/src/mv.rs b/src/uu/mv/src/mv.rs index 0ceda8e75e8..e3916300ff7 100644 --- a/src/uu/mv/src/mv.rs +++ b/src/uu/mv/src/mv.rs @@ -354,29 +354,15 @@ fn handle_two_paths(source: &Path, target: &Path, opts: &Options) -> UResult<()> } else { Err(MvError::DirectoryToNonDirectory(target.quote().to_string()).into()) } + // Check that source & target do not contain same subdir/dir when both exist + // mkdir dir1/dir2; mv dir1 dir1/dir2 + } else if target.starts_with(source) { + Err(MvError::SelfTargetSubdirectory( + source.display().to_string(), + target.display().to_string(), + ) + .into()) } else { - // Check that source & target do not contain same subdir/dir when both exist - // mkdir dir1/dir2; mv dir1 dir1/dir2 - let target_contains_itself = target - .as_os_str() - .to_str() - .ok_or("not a valid unicode string") - .and_then(|t| { - source - .as_os_str() - .to_str() - .ok_or("not a valid unicode string") - .map(|s| t.contains(s)) - }) - .unwrap(); - - if target_contains_itself { - return Err(MvError::SelfTargetSubdirectory( - source.display().to_string(), - target.display().to_string(), - ) - .into()); - } move_files_into_dir(&[source.to_path_buf()], target, opts) } } else if target.exists() && source.is_dir() { diff --git a/tests/by-util/test_mv.rs b/tests/by-util/test_mv.rs index c54d24ea906..530beb5ed83 100644 --- a/tests/by-util/test_mv.rs +++ b/tests/by-util/test_mv.rs @@ -1415,6 +1415,20 @@ fn test_mv_directory_into_subdirectory_of_itself_fails() { ); } +#[test] +fn test_mv_dir_into_dir_with_source_name_a_prefix_of_target_name() { + let (at, mut ucmd) = at_and_ucmd!(); + let source = "test"; + let target = "test2"; + + at.mkdir(source); + at.mkdir(target); + + ucmd.arg(source).arg(target).succeeds().no_output(); + + assert!(at.dir_exists(&format!("{target}/{source}"))); +} + #[test] fn test_mv_file_into_dir_where_both_are_files() { let scene = TestScenario::new(util_name!());