diff --git a/src/uu/basename/src/basename.rs b/src/uu/basename/src/basename.rs index 5450ee3f2..d9447d066 100644 --- a/src/uu/basename/src/basename.rs +++ b/src/uu/basename/src/basename.rs @@ -119,9 +119,15 @@ pub fn uu_app() -> App<'static, 'static> { } fn basename(fullname: &str, suffix: &str) -> String { - // Remove all platform-specific path separators from the end + // Remove all platform-specific path separators from the end. let path = fullname.trim_end_matches(is_separator); + // If the path contained *only* suffix characters (for example, if + // `fullname` were "///" and `suffix` were "/"), then `path` would + // be left with the empty string. In that case, we set `path` to be + // the original `fullname` to avoid returning the empty path. + let path = if path.is_empty() { fullname } else { path }; + // Convert to path buffer and get last path component let pb = PathBuf::from(path); match pb.components().last() { diff --git a/tests/by-util/test_basename.rs b/tests/by-util/test_basename.rs index d9632106e..4a3e6914a 100644 --- a/tests/by-util/test_basename.rs +++ b/tests/by-util/test_basename.rs @@ -147,3 +147,30 @@ fn invalid_utf8_args_unix() { let os_str = OsStr::from_bytes(&source[..]); test_invalid_utf8_args(os_str); } + +#[test] +fn test_root() { + new_ucmd!().arg("/").succeeds().stdout_is("/\n"); +} + +#[test] +fn test_double_slash() { + // TODO The GNU tests seem to suggest that some systems treat "//" + // as the same directory as "/" directory but not all systems. We + // should extend this test to account for that possibility. + let expected = if cfg!(windows) { "\\" } else { "/\n" }; + new_ucmd!().arg("//").succeeds().stdout_is(expected); + new_ucmd!() + .args(&["//", "/"]) + .succeeds() + .stdout_is(expected); + new_ucmd!() + .args(&["//", "//"]) + .succeeds() + .stdout_is(expected); +} + +#[test] +fn test_triple_slash() { + new_ucmd!().arg("///").succeeds().stdout_is("/\n"); +}