From 0d348f05f25b614b4c35af8a0e68156dadaed71a Mon Sep 17 00:00:00 2001 From: Jeffrey Finkelstein Date: Fri, 30 Jul 2021 11:06:55 -0400 Subject: [PATCH 1/2] basename: handle paths comprising only slashes Fix an issue where `basename` would print the empty path when provided an input comprising only slashes (for example, "/" or "//" or "///"). Now it correctly prints the path "/". --- src/uu/basename/src/basename.rs | 8 +++++++- tests/by-util/test_basename.rs | 27 +++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) 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"); +} From 8f5b785180c0a97524f7a5c0a698467c7a1e8bd1 Mon Sep 17 00:00:00 2001 From: Jeffrey Finkelstein Date: Sun, 1 Aug 2021 10:05:01 -0400 Subject: [PATCH 2/2] fixup! basename: handle paths comprising only slashes --- tests/by-util/test_basename.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/by-util/test_basename.rs b/tests/by-util/test_basename.rs index 4a3e6914a..f7332af5f 100644 --- a/tests/by-util/test_basename.rs +++ b/tests/by-util/test_basename.rs @@ -150,7 +150,8 @@ fn invalid_utf8_args_unix() { #[test] fn test_root() { - new_ucmd!().arg("/").succeeds().stdout_is("/\n"); + let expected = if cfg!(windows) { "\\\n" } else { "/\n" }; + new_ucmd!().arg("/").succeeds().stdout_is(expected); } #[test] @@ -158,7 +159,7 @@ 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" }; + let expected = if cfg!(windows) { "\\\n" } else { "/\n" }; new_ucmd!().arg("//").succeeds().stdout_is(expected); new_ucmd!() .args(&["//", "/"]) @@ -172,5 +173,6 @@ fn test_double_slash() { #[test] fn test_triple_slash() { - new_ucmd!().arg("///").succeeds().stdout_is("/\n"); + let expected = if cfg!(windows) { "\\\n" } else { "/\n" }; + new_ucmd!().arg("///").succeeds().stdout_is(expected); }