From cc157629b40748bb56ac048cb1152f2bd05a750f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20Harald=20J=C3=B8rgensen?= <58829763+adamjoer@users.noreply.github.com> Date: Mon, 13 Nov 2023 01:03:07 +0100 Subject: [PATCH] Shell: Expand glob to only directories if it ends with a slash The glob "*/" should only expand to directories, and the directories should also have a trailing slash. This commit also replaces Shell::split_path with StringView::split_view since it accomplishes the same task. --- Userland/Shell/Shell.cpp | 36 ++++++++++++------------------------ Userland/Shell/Shell.h | 1 - 2 files changed, 12 insertions(+), 25 deletions(-) diff --git a/Userland/Shell/Shell.cpp b/Userland/Shell/Shell.cpp index 62454ac157..d68daf15eb 100644 --- a/Userland/Shell/Shell.cpp +++ b/Userland/Shell/Shell.cpp @@ -252,28 +252,6 @@ bool Shell::is_glob(StringView s) return false; } -Vector Shell::split_path(StringView path) -{ - Vector parts; - - size_t substart = 0; - for (size_t i = 0; i < path.length(); i++) { - char ch = path[i]; - if (ch != '/') - continue; - size_t sublen = i - substart; - if (sublen != 0) - parts.append(path.substring_view(substart, sublen)); - substart = i + 1; - } - - size_t taillen = path.length() - substart; - if (taillen != 0) - parts.append(path.substring_view(substart, taillen)); - - return parts; -} - Vector Shell::expand_globs(StringView path, StringView base) { auto explicitly_set_base = false; @@ -281,7 +259,8 @@ Vector Shell::expand_globs(StringView path, StringView base) base = "/"sv; explicitly_set_base = true; } - auto parts = split_path(path); + + auto parts = path.split_view('/', SplitBehavior::KeepTrailingSeparator); DeprecatedString base_string = base; struct stat statbuf; if (lstat(base_string.characters(), &statbuf) < 0) { @@ -326,12 +305,19 @@ Vector Shell::expand_globs(Vector path_segments, S if (is_glob(first_segment)) { Vector result; + auto const is_glob_directory = first_segment.ends_with('/'); + if (is_glob_directory) + first_segment = first_segment.substring_view(0, first_segment.length() - 1); + Core::DirIterator di(base, Core::DirIterator::SkipParentAndBaseDir); if (di.has_error()) return {}; while (di.has_next()) { - DeprecatedString path = di.next_path(); + auto const entry = di.next().release_value(); + auto const path = entry.name; + if (is_glob_directory && entry.type != Core::DirectoryEntry::Type::Directory) + continue; // Dotfiles have to be explicitly requested if (path[0] == '.' && first_segment[0] != '.') @@ -343,6 +329,8 @@ Vector Shell::expand_globs(Vector path_segments, S if (!base.ends_with('/')) builder.append('/'); builder.append(path); + if (is_glob_directory) + builder.append('/'); result.extend(expand_globs(path_segments, builder.string_view())); } } diff --git a/Userland/Shell/Shell.h b/Userland/Shell/Shell.h index 98451ffac3..52670b5740 100644 --- a/Userland/Shell/Shell.h +++ b/Userland/Shell/Shell.h @@ -294,7 +294,6 @@ public: static SpecialCharacterEscapeMode special_character_escape_mode(u32 c, EscapeMode); static bool is_glob(StringView); - static Vector split_path(StringView); enum class ExecutableOnly { Yes,