runtime: don't execute external commands when loading ftplugins

Commit: 
https://github.com/vim/vim/commit/f7ac0ef5098856bedca26e7073594a407c05636f
Author: Christian Brabandt <[email protected]>
Date:   Wed Sep 6 20:41:25 2023 +0200

    runtime: don't execute external commands when loading ftplugins
    
    This is a followup to 816fbcc262687b81fc46f82f7bbeb1453addfe0c (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]>

diff --git a/runtime/doc/filetype.txt b/runtime/doc/filetype.txt
index 05047224f..9c092673f 100644
--- a/runtime/doc/filetype.txt
+++ b/runtime/doc/filetype.txt
@@ -1,4 +1,4 @@
-*filetype.txt*  For Vim version 9.0.  Last change: 2023 Apr 29
+*filetype.txt*  For Vim version 9.0.  Last change: 2023 Sep 06
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -419,11 +419,24 @@ ways to change this:
 3.  Docs for the default filetype plugins.             *ftplugin-docs*
 
 
+                                       *plugin_exec* *g:plugin_exec*
+Enable executing of external commands.  This was done historically for e.g.
+the perl filetype plugin (and a few others) to set the search path.
+Disabled by default for security reasons: >
+       :let g:plugin_exec = 1
+It is also possible to enable this only for certain filetypes: >
+       :let g:<filetype>_exec = 1
+So to enable this only for ruby, set the following variable: >
+       :let g:ruby_exec = 1
+
+If both, the global `plugin_exec` and the `<filetype>_exec` specific variable
+are set, the filetpe specific variable should have precedent.
+
 AWK                                                    *ft-awk-plugin*
 
 Support for features specific to GNU Awk, like @include, can be enabled by
 setting: >
-       let g:awk_is_gawk = 1
+       :let g:awk_is_gawk = 1
 
 
 CHANGELOG                                              *ft-changelog-plugin*
diff --git a/runtime/ftplugin/awk.vim b/runtime/ftplugin/awk.vim
index 1bca3ad3c..785088ff9 100644
--- a/runtime/ftplugin/awk.vim
+++ b/runtime/ftplugin/awk.vim
@@ -37,11 +37,14 @@ if exists("g:awk_is_gawk")
     let b:undo_ftplugin .= " | setl fp<"
   endif
 
-  let path = system("gawk 'BEGIN { printf ENVIRON[\"AWKPATH\"] }'")
-  let path = substitute(path, '^\.\=:\|:\.\=$\|:\.\=:', ',,', 'g') " POSIX cwd
-  let path = substitute(path, ':', ',', 'g')
+  " Disabled by default for security reasons.  
+  if get(g:, 'awk_exec', get(g:, 'plugin_exec', 0))
+    let path = system("gawk 'BEGIN { printf ENVIRON[\"AWKPATH\"] }'")
+    let path = substitute(path, '^\.\=:\|:\.\=$\|:\.\=:', ',,', 'g') " POSIX 
cwd
+    let path = substitute(path, ':', ',', 'g')
 
-  let &l:path = path
+    let &l:path = path
+  endif
   let b:undo_ftplugin .= " | setl inc< path<"
 endif
 
diff --git a/runtime/ftplugin/changelog.vim b/runtime/ftplugin/changelog.vim
index e9df63f8c..a62433378 100644
--- a/runtime/ftplugin/changelog.vim
+++ b/runtime/ftplugin/changelog.vim
@@ -55,13 +55,19 @@ if &filetype == 'changelog'
     elseif $EMAIL_ADDRESS != ""
       return $EMAIL_ADDRESS
     endif
+    let s:default_login = 'unknown'
 
-    let login = s:login()
+    " Disabled by default for security reasons.  
+    if get(g:, 'changelog_exec', get(g:, 'plugin_exec', 0))
+      let login = s:login()
+    else
+      let login = s:default_login
+    endif
     return printf('%s <%s@%s>', s:name(login), login, s:hostname())
   endfunction
 
   function! s:login()
-    return s:trimmed_system_with_default('whoami', 'unknown')
+    return s:trimmed_system_with_default('whoami', s:default_login)
   endfunction
 
   function! s:trimmed_system_with_default(command, default)
@@ -71,7 +77,7 @@ if &filetype == 'changelog'
   function! s:system_with_default(command, default)
     let output = system(a:command)
     if v:shell_error
-      return default
+      return a:default
     endif
     return output
   endfunction
diff --git a/runtime/ftplugin/perl.vim b/runtime/ftplugin/perl.vim
index 4361097f3..f3de81deb 100644
--- a/runtime/ftplugin/perl.vim
+++ b/runtime/ftplugin/perl.vim
@@ -54,10 +54,12 @@ endif
 
 " Set this once, globally.
 if !exists("perlpath")
-    " safety check: don't execute perl from current directory
     let s:tmp_cwd = getcwd()
-    if executable("perl") && (fnamemodify(exepath("perl"), ":p:h") != s:tmp_cwd
-          \ || (index(split($PATH,has("win32")? ';' : ':'), s:tmp_cwd) != -1 
&& s:tmp_cwd != '.'))
+    " safety check: don't execute perl binary by default
+    if executable("perl") && get(g:, 'perl_exec', get(g:, 'plugin_exec', 0))
+        \ && (fnamemodify(exepath("perl"), ":p:h") != s:tmp_cwd
+        \ || (index(split($PATH, has("win32") ? ';' : ':'), s:tmp_cwd) != -1
+        \ && s:tmp_cwd != '.'))
       try
        if &shellxquote != '"'
            let perlpath = system('perl -e "print join(q/,/,@INC)"')
@@ -73,7 +75,7 @@ if !exists("perlpath")
        " current directory and the directory of the current file.
        let perlpath = ".,,"
     endif
-    unlet s:tmp_cwd
+    unlet! s:tmp_cwd
 endif
 
 " Append perlpath to the existing path value, if it is set.  Since we don't
diff --git a/runtime/ftplugin/ruby.vim b/runtime/ftplugin/ruby.vim
index a424801cd..b61c1765d 100644
--- a/runtime/ftplugin/ruby.vim
+++ b/runtime/ftplugin/ruby.vim
@@ -61,6 +61,10 @@ if !exists('g:ruby_version_paths')
 endif
 
 function! s:query_path(root) abort
+  " Disabled by default for security reasons.  
+  if !get(g:, 'ruby_exec', get(g:, 'plugin_exec', 0))
+    return []
+  endif
   let code = "print $:.join %q{,}"
   if &shell =~# 'sh' && empty(&shellxquote)
     let prefix = 'env PATH='.shellescape($PATH).' '
@@ -84,7 +88,7 @@ function! s:query_path(root) abort
     else
       let path = split(system(path_check),',')
     endif
-    unlet s:tmp_cwd
+    unlet! s:tmp_cwd
     exe cd cwd
     return path
   finally
diff --git a/runtime/ftplugin/zig.vim b/runtime/ftplugin/zig.vim
index 45ea58261..2a081980c 100644
--- a/runtime/ftplugin/zig.vim
+++ b/runtime/ftplugin/zig.vim
@@ -40,17 +40,17 @@ endif
 let &l:define=' (<fn>|<const>|<var>|^\s*\#\s*define)'
 
 " Safety check: don't execute zip from current directory
-let s:tmp_cwd = getcwd()
 if !exists('g:zig_std_dir') && exists('*json_decode') &&
-    \  executable('zig') && (fnamemodify(exepath("zig"), ":p:h") != s:tmp_cwd
-          \ || (index(split($PATH,has("win32")? ';' : ':'), s:tmp_cwd) != -1 
&& s:tmp_cwd != '.'))
+    \  executable('zig') && get(g:, 'zig_exec', get(g:, 'plugin_exec', 0))
+    \ && (fnamemodify(exepath("zig"), ":p:h") != s:tmp_cwd
+    \ || (index(split($PATH,has("win32")? ';' : ':'), s:tmp_cwd) != -1 && 
s:tmp_cwd != '.'))
     silent let s:env = system('zig env')
     if v:shell_error == 0
         let g:zig_std_dir = json_decode(s:env)['std_dir']
     endif
     unlet! s:env
 endif
-unlet s:tmp_cwd
+unlet! s:tmp_cwd
 
 if exists('g:zig_std_dir')
     let &l:path = &l:path . ',' . g:zig_std_dir

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/E1qdxWS-000i4T-11%40256bit.org.

Raspunde prin e-mail lui