mirror of
https://github.com/uutils/coreutils.git
synced 2026-06-10 15:48:22 -07:00
rmdir: Remove all trailing slashes when checking for symlinks (#9983)
* rmdir: Remove all trailing slashes when checking for symlinks rmdir: cargo fmt l * rmdir: Extract removal of trailing slashes to helper func * rmdir: Add regression test for removal of trailing slashes when checking for symlink * rmdir: add cfg flag to helper func which is only used on unix
This commit is contained in:
@@ -66,10 +66,11 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||
Ok(path.metadata()?.file_type().is_dir())
|
||||
}
|
||||
|
||||
let bytes = path.as_os_str().as_bytes();
|
||||
let mut bytes = path.as_os_str().as_bytes();
|
||||
if error.raw_os_error() == Some(libc::ENOTDIR) && bytes.ends_with(b"/") {
|
||||
// Strip the trailing slash or .symlink_metadata() will follow the symlink
|
||||
let no_slash: &Path = OsStr::from_bytes(&bytes[..bytes.len() - 1]).as_ref();
|
||||
bytes = strip_trailing_slashes_from_path(bytes);
|
||||
let no_slash: &Path = OsStr::from_bytes(bytes).as_ref();
|
||||
if no_slash.is_symlink() && points_to_directory(no_slash).unwrap_or(true) {
|
||||
show_error!(
|
||||
"{}",
|
||||
@@ -119,6 +120,15 @@ fn remove_single(path: &Path, opts: Opts) -> Result<(), Error<'_>> {
|
||||
remove_dir(path).map_err(|error| Error { error, path })
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
fn strip_trailing_slashes_from_path(path: &[u8]) -> &[u8] {
|
||||
let mut end = path.len();
|
||||
while end > 0 && path[end - 1] == b'/' {
|
||||
end -= 1;
|
||||
}
|
||||
&path[..end]
|
||||
}
|
||||
|
||||
// POSIX: https://pubs.opengroup.org/onlinepubs/009696799/functions/rmdir.html
|
||||
#[cfg(not(windows))]
|
||||
const NOT_EMPTY_CODES: &[i32] = &[libc::ENOTEMPTY, libc::EEXIST];
|
||||
|
||||
@@ -243,3 +243,18 @@ fn test_rmdir_remove_symlink_dangling() {
|
||||
.fails()
|
||||
.stderr_is("rmdir: failed to remove 'dl/': Symbolic link not followed\n");
|
||||
}
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
#[test]
|
||||
fn test_rmdir_remove_symlink_dir_with_trailing_slashes() {
|
||||
// a symlink with trailing slashes should still be printing the 'Symbolic link not followed'
|
||||
// message
|
||||
let (at, mut ucmd) = at_and_ucmd!();
|
||||
|
||||
at.mkdir("dir");
|
||||
at.symlink_dir("dir", "dl");
|
||||
|
||||
ucmd.arg("dl////")
|
||||
.fails()
|
||||
.stderr_is("rmdir: failed to remove 'dl////': Symbolic link not followed\n");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user