Skip to content

Commit f7ac0ef

Browse files
chrisbraTim Pope
andcommitted
runtime: don't execute external commands when loading ftplugins
This is a followup to 816fbcc (patch 9.0.1833: [security] runtime file fixes) It basically disables that external commands are run on loading of the filetype plugin, **unless** the user has set the `g:plugin_exec = 1` global variable in their configuration or for a specific filetype the variable g:<filetype>_exec=1. There are a few more plugins, that may execute system commands like debchangelog, gitcommit, sh, racket, zsh, ps1 but those do at least do not run those commands by default during loading of the filetype plugin (there the command is mostly run as convenience for auto-completion or to provide documentation lookup). closes: #13034 Signed-off-by: Christian Brabandt <[email protected]> Co-authored-by: Tim Pope <[email protected]>
1 parent 1689e84 commit f7ac0ef

6 files changed

Lines changed: 46 additions & 18 deletions

File tree

runtime/doc/filetype.txt

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
*filetype.txt* For Vim version 9.0. Last change: 2023 Apr 29
1+
*filetype.txt* For Vim version 9.0. Last change: 2023 Sep 06
22

33

44
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -419,11 +419,24 @@ ways to change this:
419419
3. Docs for the default filetype plugins. *ftplugin-docs*
420420

421421

422+
*plugin_exec* *g:plugin_exec*
423+
Enable executing of external commands. This was done historically for e.g.
424+
the perl filetype plugin (and a few others) to set the search path.
425+
Disabled by default for security reasons: >
426+
:let g:plugin_exec = 1
427+
It is also possible to enable this only for certain filetypes: >
428+
:let g:<filetype>_exec = 1
429+
So to enable this only for ruby, set the following variable: >
430+
:let g:ruby_exec = 1
431+
432+
If both, the global `plugin_exec` and the `<filetype>_exec` specific variable
433+
are set, the filetpe specific variable should have precedent.
434+
422435
AWK *ft-awk-plugin*
423436

424437
Support for features specific to GNU Awk, like @include, can be enabled by
425438
setting: >
426-
let g:awk_is_gawk = 1
439+
:let g:awk_is_gawk = 1
427440
428441
429442
CHANGELOG *ft-changelog-plugin*

runtime/ftplugin/awk.vim

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,14 @@ if exists("g:awk_is_gawk")
3737
let b:undo_ftplugin .= " | setl fp<"
3838
endif
3939

40-
let path = system("gawk 'BEGIN { printf ENVIRON[\"AWKPATH\"] }'")
41-
let path = substitute(path, '^\.\=:\|:\.\=$\|:\.\=:', ',,', 'g') " POSIX cwd
42-
let path = substitute(path, ':', ',', 'g')
40+
" Disabled by default for security reasons.
41+
if get(g:, 'awk_exec', get(g:, 'plugin_exec', 0))
42+
let path = system("gawk 'BEGIN { printf ENVIRON[\"AWKPATH\"] }'")
43+
let path = substitute(path, '^\.\=:\|:\.\=$\|:\.\=:', ',,', 'g') " POSIX cwd
44+
let path = substitute(path, ':', ',', 'g')
4345

44-
let &l:path = path
46+
let &l:path = path
47+
endif
4548
let b:undo_ftplugin .= " | setl inc< path<"
4649
endif
4750

runtime/ftplugin/changelog.vim

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,19 @@ if &filetype == 'changelog'
5555
elseif $EMAIL_ADDRESS != ""
5656
return $EMAIL_ADDRESS
5757
endif
58+
let s:default_login = 'unknown'
5859

59-
let login = s:login()
60+
" Disabled by default for security reasons.
61+
if get(g:, 'changelog_exec', get(g:, 'plugin_exec', 0))
62+
let login = s:login()
63+
else
64+
let login = s:default_login
65+
endif
6066
return printf('%s <%s@%s>', s:name(login), login, s:hostname())
6167
endfunction
6268

6369
function! s:login()
64-
return s:trimmed_system_with_default('whoami', 'unknown')
70+
return s:trimmed_system_with_default('whoami', s:default_login)
6571
endfunction
6672

6773
function! s:trimmed_system_with_default(command, default)
@@ -71,7 +77,7 @@ if &filetype == 'changelog'
7177
function! s:system_with_default(command, default)
7278
let output = system(a:command)
7379
if v:shell_error
74-
return default
80+
return a:default
7581
endif
7682
return output
7783
endfunction

runtime/ftplugin/perl.vim

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,12 @@ endif
5454

5555
" Set this once, globally.
5656
if !exists("perlpath")
57-
" safety check: don't execute perl from current directory
5857
let s:tmp_cwd = getcwd()
59-
if executable("perl") && (fnamemodify(exepath("perl"), ":p:h") != s:tmp_cwd
60-
\ || (index(split($PATH,has("win32")? ';' : ':'), s:tmp_cwd) != -1 && s:tmp_cwd != '.'))
58+
" safety check: don't execute perl binary by default
59+
if executable("perl") && get(g:, 'perl_exec', get(g:, 'plugin_exec', 0))
60+
\ && (fnamemodify(exepath("perl"), ":p:h") != s:tmp_cwd
61+
\ || (index(split($PATH, has("win32") ? ';' : ':'), s:tmp_cwd) != -1
62+
\ && s:tmp_cwd != '.'))
6163
try
6264
if &shellxquote != '"'
6365
let perlpath = system('perl -e "print join(q/,/,@INC)"')
@@ -73,7 +75,7 @@ if !exists("perlpath")
7375
" current directory and the directory of the current file.
7476
let perlpath = ".,,"
7577
endif
76-
unlet s:tmp_cwd
78+
unlet! s:tmp_cwd
7779
endif
7880

7981
" Append perlpath to the existing path value, if it is set. Since we don't

runtime/ftplugin/ruby.vim

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ if !exists('g:ruby_version_paths')
6161
endif
6262

6363
function! s:query_path(root) abort
64+
" Disabled by default for security reasons.
65+
if !get(g:, 'ruby_exec', get(g:, 'plugin_exec', 0))
66+
return []
67+
endif
6468
let code = "print $:.join %q{,}"
6569
if &shell =~# 'sh' && empty(&shellxquote)
6670
let prefix = 'env PATH='.shellescape($PATH).' '
@@ -84,7 +88,7 @@ function! s:query_path(root) abort
8488
else
8589
let path = split(system(path_check),',')
8690
endif
87-
unlet s:tmp_cwd
91+
unlet! s:tmp_cwd
8892
exe cd cwd
8993
return path
9094
finally

runtime/ftplugin/zig.vim

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,17 @@ endif
4040
let &l:define='\v(<fn>|<const>|<var>|^\s*\#\s*define)'
4141

4242
" Safety check: don't execute zip from current directory
43-
let s:tmp_cwd = getcwd()
4443
if !exists('g:zig_std_dir') && exists('*json_decode') &&
45-
\ executable('zig') && (fnamemodify(exepath("zig"), ":p:h") != s:tmp_cwd
46-
\ || (index(split($PATH,has("win32")? ';' : ':'), s:tmp_cwd) != -1 && s:tmp_cwd != '.'))
44+
\ executable('zig') && get(g:, 'zig_exec', get(g:, 'plugin_exec', 0))
45+
\ && (fnamemodify(exepath("zig"), ":p:h") != s:tmp_cwd
46+
\ || (index(split($PATH,has("win32")? ';' : ':'), s:tmp_cwd) != -1 && s:tmp_cwd != '.'))
4747
silent let s:env = system('zig env')
4848
if v:shell_error == 0
4949
let g:zig_std_dir = json_decode(s:env)['std_dir']
5050
endif
5151
unlet! s:env
5252
endif
53-
unlet s:tmp_cwd
53+
unlet! s:tmp_cwd
5454

5555
if exists('g:zig_std_dir')
5656
let &l:path = &l:path . ',' . g:zig_std_dir

0 commit comments

Comments
 (0)