mirror of
https://github.com/vim/vim.git
synced 2026-05-28 00:21:37 +02:00
patch 9.2.0418: wildcards in expanded env vars reinterpreted by glob
Problem: With $d='[dir]', `:e $d/file.txt` opens the wrong file,
`:e $d/<Tab>` fails to complete, and `glob('$d/*')` returns
nothing. Wildcard characters inside expanded environment
variables get picked up by globbing again.
Solution: Turn the 4th parameter of expand_env_esc() from a bool into a
string of characters to escape in each expanded value. Callers
that pass the result to wildcard expansion should include
PATH_ESC_WILDCARDS in addition to " \t" (glepnir).
closes: #20053
Signed-off-by: glepnir <glephunter@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
af494af5ff
commit
20e98ff1cc
@@ -2113,7 +2113,6 @@ es_ES.utf-8" gives an error and doesn't switch messages. (Dominique Pelle,
|
||||
|
||||
When $HOME contains special characters, such as a comma, escape them when used
|
||||
in an option. (Michael Hordijk, 2009 May 5)
|
||||
Turn "esc" argument of expand_env_esc() into string of chars to be escaped.
|
||||
|
||||
Should make 'ignorecase' global-local, so that it makes sense setting it from
|
||||
a modeline.
|
||||
|
||||
+1
-1
@@ -1254,7 +1254,7 @@ showmatches_oneline(
|
||||
// Expansion was done before and special characters
|
||||
// were escaped, need to halve backslashes. Also
|
||||
// $HOME has been replaced with ~/.
|
||||
exp_path = expand_env_save_opt(matches[j], TRUE);
|
||||
exp_path = expand_env_save_opt(matches[j], TRUE, NULL);
|
||||
path = exp_path != NULL ? exp_path : matches[j];
|
||||
halved_slash = backslash_halve_save(path);
|
||||
isdir = mch_isdir(halved_slash != NULL ? halved_slash
|
||||
|
||||
+2
-1
@@ -5246,7 +5246,8 @@ expand_filename(
|
||||
|| vim_strchr(eap->arg, '~') != NULL)
|
||||
{
|
||||
expand_env_esc(eap->arg, NameBuff, MAXPATHL,
|
||||
TRUE, TRUE, NULL);
|
||||
(char_u *)(" \t" PATH_ESC_WILDCARDS),
|
||||
TRUE, NULL);
|
||||
has_wildcards = mch_has_wildcard(NameBuff);
|
||||
p = NameBuff;
|
||||
}
|
||||
|
||||
+1
-1
@@ -4158,7 +4158,7 @@ gen_expand_wildcards(
|
||||
*/
|
||||
if ((has_env_var(p) && !(flags & EW_NOTENV)) || *p == '~')
|
||||
{
|
||||
p = expand_env_save_opt(p, TRUE);
|
||||
p = expand_env_save_opt(p, TRUE, (char_u *)PATH_ESC_WILDCARDS);
|
||||
if (p == NULL)
|
||||
p = pat[i];
|
||||
#ifdef UNIX
|
||||
|
||||
+1
-1
@@ -1808,7 +1808,7 @@ find_file_in_path_option(
|
||||
// copy file name into NameBuff, expanding environment variables
|
||||
save_char = ptr[len];
|
||||
ptr[len] = NUL;
|
||||
file_to_findlen = expand_env_esc(ptr, NameBuff, MAXPATHL, FALSE, TRUE, NULL);
|
||||
file_to_findlen = expand_env_esc(ptr, NameBuff, MAXPATHL, NULL, TRUE, NULL);
|
||||
ptr[len] = save_char;
|
||||
|
||||
vim_free(*file_to_find);
|
||||
|
||||
+11
-9
@@ -1398,7 +1398,7 @@ init_vimdir(void)
|
||||
char_u *
|
||||
expand_env_save(char_u *src)
|
||||
{
|
||||
return expand_env_save_opt(src, FALSE);
|
||||
return expand_env_save_opt(src, FALSE, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1406,13 +1406,13 @@ expand_env_save(char_u *src)
|
||||
* expand "~" at the start.
|
||||
*/
|
||||
char_u *
|
||||
expand_env_save_opt(char_u *src, int one)
|
||||
expand_env_save_opt(char_u *src, int one, char_u *esc_chars)
|
||||
{
|
||||
char_u *p;
|
||||
|
||||
p = alloc(MAXPATHL);
|
||||
if (p != NULL)
|
||||
expand_env_esc(src, p, MAXPATHL, FALSE, one, NULL);
|
||||
expand_env_esc(src, p, MAXPATHL, esc_chars, one, NULL);
|
||||
return p;
|
||||
}
|
||||
|
||||
@@ -1428,7 +1428,7 @@ expand_env(
|
||||
char_u *dst, // where to put the result
|
||||
int dstlen) // maximum length of the result
|
||||
{
|
||||
return expand_env_esc(src, dst, dstlen, FALSE, FALSE, NULL);
|
||||
return expand_env_esc(src, dst, dstlen, NULL, FALSE, NULL);
|
||||
}
|
||||
|
||||
size_t
|
||||
@@ -1436,7 +1436,7 @@ expand_env_esc(
|
||||
char_u *srcp, // input string e.g. "$HOME/vim.hlp"
|
||||
char_u *dst, // where to put the result
|
||||
int dstlen, // maximum length of the result
|
||||
int esc, // escape spaces in expanded variables
|
||||
char_u *esc_chars, // chars to escape in expanded vars
|
||||
int one, // "srcp" is one file name
|
||||
char_u *startstr) // start again after this (can be NULL)
|
||||
{
|
||||
@@ -1655,11 +1655,13 @@ expand_env_esc(
|
||||
}
|
||||
#endif
|
||||
|
||||
// If "var" contains white space, escape it with a backslash.
|
||||
// Required for ":e ~/tt" when $HOME includes a space.
|
||||
if (esc && var != NULL && vim_strpbrk(var, (char_u *)" \t") != NULL)
|
||||
// If "var" contains any character from "esc_chars", escape it
|
||||
// with a backslash. The historical use is escaping spaces so
|
||||
// that ":e ~/tt" works when $HOME contains a space.
|
||||
if (esc_chars != NULL && var != NULL
|
||||
&& vim_strpbrk(var, esc_chars) != NULL)
|
||||
{
|
||||
char_u *p = vim_strsave_escaped(var, (char_u *)" \t");
|
||||
char_u *p = vim_strsave_escaped(var, esc_chars);
|
||||
|
||||
if (p != NULL)
|
||||
{
|
||||
|
||||
+2
-1
@@ -3264,7 +3264,8 @@ option_expand(int opt_idx, char_u *val)
|
||||
char_u ** var = (char_u **)options[opt_idx].var;
|
||||
int esc = var == &p_tags || var == &p_path;
|
||||
|
||||
expand_env_esc(val, NameBuff, MAXPATHL, esc, FALSE,
|
||||
expand_env_esc(val, NameBuff, MAXPATHL,
|
||||
esc ? (char_u *)" \t" : NULL, FALSE,
|
||||
#ifdef FEAT_SPELL
|
||||
var == &p_sps ? (char_u *)"file:" :
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -392,7 +392,7 @@ ex_profile(exarg_T *eap)
|
||||
if (len == 5 && STRNCMP(eap->arg, "start", 5) == 0 && *e != NUL)
|
||||
{
|
||||
VIM_CLEAR(profile_fname);
|
||||
profile_fname = expand_env_save_opt(e, TRUE);
|
||||
profile_fname = expand_env_save_opt(e, TRUE, NULL);
|
||||
do_profiling = PROF_YES;
|
||||
profile_zero(&prof_wait_time);
|
||||
set_vim_var_nr(VV_PROFILING, 1L);
|
||||
|
||||
+2
-2
@@ -29,9 +29,9 @@ void free_homedir(void);
|
||||
void free_users(void);
|
||||
void init_vimdir(void);
|
||||
char_u *expand_env_save(char_u *src);
|
||||
char_u *expand_env_save_opt(char_u *src, int one);
|
||||
char_u *expand_env_save_opt(char_u *src, int one, char_u *esc_chars);
|
||||
size_t expand_env(char_u *src, char_u *dst, int dstlen);
|
||||
size_t expand_env_esc(char_u *srcp, char_u *dst, int dstlen, int esc, int one, char_u *startstr);
|
||||
size_t expand_env_esc(char_u *srcp, char_u *dst, int dstlen, char_u *esc_chars, int one, char_u *startstr);
|
||||
char_u *vim_getenv(char_u *name, int *mustfree);
|
||||
void vim_unsetenv(char_u *var);
|
||||
void vim_unsetenv_ext(char_u *var);
|
||||
|
||||
@@ -5506,4 +5506,31 @@ func Test_wildmode_noinsert()
|
||||
delfunc T
|
||||
endfunc
|
||||
|
||||
func Test_cmdline_compl_env_var_wildcard()
|
||||
CheckUnix
|
||||
|
||||
let d = tempname()
|
||||
call mkdir(d .. '/[x]', 'pR')
|
||||
call writefile(['hello'], d .. '/[x]/file.txt')
|
||||
let $XWILD = d .. '/[x]'
|
||||
|
||||
call feedkeys(":e $XWILD/fi\<Tab>\<C-B>\"\<CR>", 'xt')
|
||||
call assert_match('\[x\]/file\.txt$', @:)
|
||||
call assert_equal([d .. '/[x]/file.txt'], glob('$XWILD/*', 0, 1))
|
||||
|
||||
edit $XWILD/file.txt
|
||||
call assert_equal('hello', getline(1))
|
||||
bwipe!
|
||||
|
||||
if has('profile')
|
||||
let prof = d .. '/[x]/prof.out'
|
||||
profile start $XWILD/prof.out
|
||||
profile stop
|
||||
call assert_true(filereadable(prof))
|
||||
call delete(prof)
|
||||
endif
|
||||
|
||||
unlet $XWILD
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
@@ -729,6 +729,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
418,
|
||||
/**/
|
||||
417,
|
||||
/**/
|
||||
|
||||
@@ -3098,4 +3098,17 @@ long elapsed(DWORD start_tick);
|
||||
// Flags used by getvcol()
|
||||
#define GETVCOL_END_EXCL_LBR 1
|
||||
|
||||
// Used by expand_env_esc() callers that feed the result to
|
||||
// wildcard expansion, so that such characters embedded in
|
||||
// environment variable values are treated as literal.
|
||||
#ifdef VMS
|
||||
# define PATH_ESC_WILDCARDS "*?%"
|
||||
#else
|
||||
# ifdef MSWIN
|
||||
# define PATH_ESC_WILDCARDS "*?["
|
||||
# else
|
||||
# define PATH_ESC_WILDCARDS "*?[{"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif // VIM__H
|
||||
|
||||
Reference in New Issue
Block a user