diff options
author | zeertzjq <zeertzjq@outlook.com> | 2023-09-28 05:09:21 +0800 |
---|---|---|
committer | zeertzjq <zeertzjq@outlook.com> | 2023-09-29 06:07:27 +0800 |
commit | 92e40f8d185e3da8fc97b7a48041afc3fd568d29 (patch) | |
tree | 62c53edf29886da5ef4fadee8d46f62d5d6b707a /src | |
parent | 7f58b2bb6a1a667689d450d9e9738d68a91f0518 (diff) | |
download | rneovim-92e40f8d185e3da8fc97b7a48041afc3fd568d29.tar.gz rneovim-92e40f8d185e3da8fc97b7a48041afc3fd568d29.tar.bz2 rneovim-92e40f8d185e3da8fc97b7a48041afc3fd568d29.zip |
vim-patch:9.0.1946: filename expansion using ** in bash may fail
Problem: filename expansion using ** in bash may fail
Solution: Try to enable the globstar setting
Starting with bash 4.0 it supports extended globbing using the globstar
shell option. This makes matching recursively below a certain directory
using the ** pattern work as expected nowadays. However, we need to
explicitly enable this using the 'shopt -s globstar' bash command.
So let's check the bash environment variable $BASH_VERSINFO (which is
supported since bash 3.0 and conditionally enable the globstar option,
if the major version is at least 4. For older bashs, this at least
shouldn't cause errors (unless one is using really ancient bash 2.X or
something).
closes: vim/vim#13002
closes: vim/vim#13144
https://github.com/vim/vim/commit/9eb1ce531527a7177d16373b0f8689bbcd3d5f73
Co-authored-by: Christian Brabandt <cb@256bit.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/os/shell.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/src/nvim/os/shell.c b/src/nvim/os/shell.c index 1cd560c5ef..582135349f 100644 --- a/src/nvim/os/shell.c +++ b/src/nvim/os/shell.c @@ -134,6 +134,8 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in #define STYLE_VIMGLOB 2 // use "vimglob", for Posix sh #define STYLE_PRINT 3 // use "print -N", for zsh #define STYLE_BT 4 // `cmd` expansion, execute the pattern directly +#define STYLE_GLOBSTAR 5 // use extended shell glob for bash (this uses extended + // globbing functionality with globstar, needs bash > 4) int shell_style = STYLE_ECHO; int check_spaces; static bool did_find_nul = false; @@ -141,6 +143,9 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in // vimglob() function to define for Posix shell static char *sh_vimglob_func = "vimglob() { while [ $# -ge 1 ]; do echo \"$1\"; shift; done }; vimglob >"; + // vimglob() function with globstar setting enabled, only for bash >= 4.X + static char *sh_globstar_opt = + "[[ ${BASH_VERSINFO[0]} -ge 4 ]] && shopt -s globstar; "; bool is_fish_shell = #if defined(UNIX) @@ -190,6 +195,8 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in // If we use *zsh, "print -N" will work better than "glob". // STYLE_VIMGLOB: NL separated // If we use *sh*, we define "vimglob()". + // STYLE_GLOBSTAR: NL separated + // If we use *bash*, we define "vimglob() and enable globstar option". // STYLE_ECHO: space separated. // A shell we don't know, stay safe and use "echo". if (num_pat == 1 && *pat[0] == '`' @@ -203,9 +210,12 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in shell_style = STYLE_PRINT; } } - if (shell_style == STYLE_ECHO - && strstr(path_tail(p_sh), "sh") != NULL) { - shell_style = STYLE_VIMGLOB; + if (shell_style == STYLE_ECHO) { + if (strstr(path_tail(p_sh), "bash") != NULL) { + shell_style = STYLE_GLOBSTAR; + } else if (strstr(path_tail(p_sh), "sh") != NULL) { + shell_style = STYLE_VIMGLOB; + } } // Compute the length of the command. We need 2 extra bytes: for the @@ -214,6 +224,8 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in len = strlen(tempname) + 29; if (shell_style == STYLE_VIMGLOB) { len += strlen(sh_vimglob_func); + } else if (shell_style == STYLE_GLOBSTAR) { + len += strlen(sh_vimglob_func) + strlen(sh_globstar_opt); } for (i = 0; i < num_pat; i++) { @@ -281,6 +293,9 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in STRCAT(command, "print -N >"); } else if (shell_style == STYLE_VIMGLOB) { STRCAT(command, sh_vimglob_func); + } else if (shell_style == STYLE_GLOBSTAR) { + STRCAT(command, sh_globstar_opt); + STRCAT(command, sh_vimglob_func); } else { STRCAT(command, "echo >"); } @@ -430,7 +445,9 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in p = skipwhite(p); // skip to next entry } // file names are separated with NL - } else if (shell_style == STYLE_BT || shell_style == STYLE_VIMGLOB) { + } else if (shell_style == STYLE_BT + || shell_style == STYLE_VIMGLOB + || shell_style == STYLE_GLOBSTAR) { buffer[len] = NUL; // make sure the buffer ends in NUL p = buffer; for (i = 0; *p != NUL; i++) { // count number of entries @@ -496,7 +513,7 @@ int os_expand_wildcards(int num_pat, char **pat, int *num_file, char ***file, in (*file)[i] = p; // Space or NL separates if (shell_style == STYLE_ECHO || shell_style == STYLE_BT - || shell_style == STYLE_VIMGLOB) { + || shell_style == STYLE_VIMGLOB || shell_style == STYLE_GLOBSTAR) { while (!(shell_style == STYLE_ECHO && *p == ' ') && *p != '\n' && *p != NUL) { p++; |