diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 4878484f7d..a5e3d3d686 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -4806,6 +4806,7 @@ A jump table for the options with a short description can be found at |Q_op|. *'path'* *'pa'* *E343* *E345* *E347* *E854* 'path' 'pa' string (default ".,,") global or local to buffer |global-local| + Disallowed in |modeline|. |no-modeline-option| This is a list of directories which will be searched when using the |gf|, [f, ]f, ^Wf, |:find|, |:sfind|, |:tabfind| and other commands, provided that the file being searched for has a relative path (not diff --git a/src/nvim/options.lua b/src/nvim/options.lua index f9ed8c0480..003f2aebd4 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -6556,6 +6556,7 @@ local options = { full_name = 'path', list = 'comma', scope = { 'global', 'buf' }, + secure = true, short_desc = N_('list of directories searched with "gf" et.al.'), tags = { 'E343', 'E345', 'E347', 'E854' }, type = 'string', diff --git a/src/nvim/path.c b/src/nvim/path.c index 85728667f8..0860671a37 100644 --- a/src/nvim/path.c +++ b/src/nvim/path.c @@ -898,6 +898,11 @@ static void expand_path_option(char *curdir, char *path_option, garray_T *gap) while (*path_option != NUL) { size_t buflen = copy_option_part(&path_option, buf, MAXPATHL, " ,"); + // do not expand backticks, could have been set via a modeline + if (vim_strchr(buf, '`') != NULL) { + continue; + } + if (buf[0] == '.' && (buf[1] == NUL || vim_ispathsep(buf[1]))) { // Relative to current buffer: // "/path/file" + "." -> "/path/" diff --git a/test/old/testdir/test_find_complete.vim b/test/old/testdir/test_find_complete.vim index 32ca9672ef..8b8b71c303 100644 --- a/test/old/testdir/test_find_complete.vim +++ b/test/old/testdir/test_find_complete.vim @@ -10,7 +10,7 @@ func Test_find_complete() call delete("Xfind", "rf") let cwd = getcwd() let test_out = cwd . '/test.out' - call mkdir('Xfind') + call mkdir('Xfind', 'R') cd Xfind new @@ -158,6 +158,24 @@ func Test_find_complete() enew | only call chdir(cwd) - call delete('Xfind', 'rf') set path& endfunc + +" Verify that backticks in 'path' are not executed +func Test_find_completion_backtick_in_path() + CheckUnix + CheckExecutable id + + new Xpoc.c + setl path+=`id>Xrce_marker` + " Triggering completion must not execute the backtick command. + call getcompletion('', 'file_in_path') + call assert_false(filereadable('Xrce_marker')) + call feedkeys(":find \t\n", "xt") + call assert_false(filereadable('Xrce_marker')) + + bwipe! + call delete('Xrce_marker') +endfunc + +" vim: shiftwidth=2 sts=2 expandtab diff --git a/test/old/testdir/test_modeline.vim b/test/old/testdir/test_modeline.vim index 3c6dd6bc85..0a0594d63d 100644 --- a/test/old/testdir/test_modeline.vim +++ b/test/old/testdir/test_modeline.vim @@ -559,4 +559,18 @@ func Test_modeline_nowrap_lcs_extends() set equalalways& endfunc +" Verify that backticks in 'path' set from a modeline are not executed +func Test_path_modeline() + let lines =<< trim END + // vim: set path+=foobar : + END + call writefile(lines, 'Xpoc.c', 'D') + + set nomodelinestrict modeline + call assert_fails('split Xpoc.c', 'E520:') + + bwipe! + set modelinestrict& modeline& +endfunc + " vim: shiftwidth=2 sts=2 expandtab