Commit: runtime(getscript,vimball,rust): Use correct shellescape() form for ! ex cmd

1 view
Skip to first unread message

Christian Brabandt

unread,
May 20, 2026, 2:15:16 PM (10 hours ago) May 20
to vim...@googlegroups.com
runtime(getscript,vimball,rust): Use correct shellescape() form for ! ex cmd

Commit: https://github.com/vim/vim/commit/129486193c16bb5c0208eff5501f9e665b7c4803
Author: Christian Brabandt <c...@256bit.org>
Date: Wed May 20 17:56:05 2026 +0000

runtime(getscript,vimball,rust): Use correct shellescape() form for ! ex cmd

Problem: shellescape() called without {special} flag for :! ex command
Solution: Pass 1 as second argument to shellescape() in :! contexts

related: Commit: 3fb5e58fbc63d86a3e65f1a141b0d67af2 (patch 9.2.0479:
[security]: runtime(tar): command injection in tar plugin)

Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/runtime/autoload/getscript.vim b/runtime/autoload/getscript.vim
index 27a5a4953..04dd19a4c 100644
--- a/runtime/autoload/getscript.vim
+++ b/runtime/autoload/getscript.vim
@@ -15,6 +15,7 @@
" 2025 Feb 28 by Vim Project: add support for bzip3 (#16755)
" 2025 May 11 by Vim Project: check network connectivity (#17249)
" 2025 Dec 21 by Vim Project: make the wget check more robust (#18987)
+" 2026 May 20 by Vim Project: use correct shellescape() with ! command
" }}}
"
" GetLatestVimScripts: 642 1 :AutoInstall: getscript.vim
@@ -433,9 +434,9 @@ fun! s:GetOneScript(...)
let itry= 1
while itry <= 3
if has("win32") || has("win16") || has("win95")
- new|exe "silent r!".g:GetLatestVimScripts_wget." ".g:GetLatestVimScripts_options." ".shellescape(tmpfile).' '.shellescape(scriptaddr)|bw!
+ new|exe "silent r!".g:GetLatestVimScripts_wget." ".g:GetLatestVimScripts_options." ".shellescape(tmpfile,1).' '.shellescape(scriptaddr,1)|bw!
else
- exe "silent !".g:GetLatestVimScripts_wget." ".g:GetLatestVimScripts_options." ".shellescape(tmpfile)." ".shellescape(scriptaddr)
+ exe "silent !".g:GetLatestVimScripts_wget." ".g:GetLatestVimScripts_options." ".shellescape(tmpfile,1)." ".shellescape(scriptaddr,1)
endif
if itry == 1
exe "silent vsplit ".fnameescape(tmpfile)
@@ -503,9 +504,9 @@ fun! s:GetOneScript(...)
" -----------------------------------------------------------------------------
echomsg ".downloading new <".sname.">"
if has("win32") || has("win16") || has("win95")
- new|exe "silent r!".g:GetLatestVimScripts_wget." ".g:GetLatestVimScripts_options." ".shellescape(sname)." ".shellescape(g:GetLatestVimScripts_downloadaddr.latestsrcid)|bw!
+ new|exe "silent r!".g:GetLatestVimScripts_wget." ".g:GetLatestVimScripts_options." ".shellescape(sname,1)." ".shellescape(g:GetLatestVimScripts_downloadaddr.latestsrcid,1)|bw!
else
- exe "silent !".g:GetLatestVimScripts_wget." ".g:GetLatestVimScripts_options." ".shellescape(sname)." ".shellescape(g:GetLatestVimScripts_downloadaddr.latestsrcid)
+ exe "silent !".g:GetLatestVimScripts_wget." ".g:GetLatestVimScripts_options." ".shellescape(sname,1)." ".shellescape(g:GetLatestVimScripts_downloadaddr.latestsrcid,1)
endif

" --------------------------------------------------------------------------
@@ -513,7 +514,7 @@ fun! s:GetOneScript(...)
" --------------------------------------------------------------------------
if doautoinstall
if filereadable(sname)
- exe "silent !".g:GetLatestVimScripts_mv." ".shellescape(sname)." ".shellescape(s:autoinstall)
+ exe "silent !".g:GetLatestVimScripts_mv." ".shellescape(sname,1)." ".shellescape(s:autoinstall,1)
let curdir = fnameescape(substitute(getcwd(),'\','/','ge'))
let installdir= curdir."/Installed"
if !isdirectory(installdir)
@@ -532,33 +533,33 @@ fun! s:GetOneScript(...)

" decompress
if sname =~ '\.bz2$'
- exe "sil !".g:GetLatestVimScripts_bunzip2." ".shellescape(sname)
+ exe "sil !".g:GetLatestVimScripts_bunzip2." ".shellescape(sname,1)
let sname= substitute(sname,'\.bz2$','','')
elseif sname =~ '\.bz3$'
- exe "sil !".g:GetLatestVimScripts_bunzip3." ".shellescape(sname)
+ exe "sil !".g:GetLatestVimScripts_bunzip3." ".shellescape(sname,1)
let sname= substitute(sname,'\.bz3$','','')
elseif sname =~ '\.gz$'
- exe "sil !".g:GetLatestVimScripts_gunzip." ".shellescape(sname)
+ exe "sil !".g:GetLatestVimScripts_gunzip." ".shellescape(sname,1)
let sname= substitute(sname,'\.gz$','','')
elseif sname =~ '\.xz$'
- exe "sil !".g:GetLatestVimScripts_unxz." ".shellescape(sname)
+ exe "sil !".g:GetLatestVimScripts_unxz." ".shellescape(sname,1)
let sname= substitute(sname,'\.xz$','','')
else
endif

" distribute archive(.zip, .tar, .vba, .vmb, ...) contents
if sname =~ '\.zip$'
- exe "silent !".g:GetLatestVimScripts_unzip." -o ".shellescape(sname)
+ exe "silent !".g:GetLatestVimScripts_unzip." -o ".shellescape(sname,1)
elseif sname =~ '\.tar$'
- exe "silent !tar -xvf ".shellescape(sname)
+ exe "silent !tar -xvf ".shellescape(sname,1)
elseif sname =~ '\.tgz$'
- exe "silent !tar -zxvf ".shellescape(sname)
+ exe "silent !tar -zxvf ".shellescape(sname,1)
elseif sname =~ '\.taz$'
- exe "silent !tar -Zxvf ".shellescape(sname)
+ exe "silent !tar -Zxvf ".shellescape(sname,1)
elseif sname =~ '\.tbz$'
- exe "silent !tar -jxvf ".shellescape(sname)
+ exe "silent !tar -jxvf ".shellescape(sname,1)
elseif sname =~ '\.txz$'
- exe "silent !tar -Jxvf ".shellescape(sname)
+ exe "silent !tar -Jxvf ".shellescape(sname,1)
elseif sname =~ '\.vba$\|\.vmb$'
silent 1split
if exists("g:vimball_home")
@@ -579,12 +580,12 @@ fun! s:GetOneScript(...)
" move plugin to plugin/ or AsNeeded/ directory
" ---------------------------------------------
if sname =~ '.vim$'
- exe "silent !".g:GetLatestVimScripts_mv." ".shellescape(sname)." ".tgtdir
+ exe "silent !".g:GetLatestVimScripts_mv." ".shellescape(sname,1)." ".tgtdir
else
- exe "silent !".g:GetLatestVimScripts_mv." ".shellescape(sname)." ".installdir
+ exe "silent !".g:GetLatestVimScripts_mv." ".shellescape(sname,1)." ".installdir
endif
if tgtdir != "plugin"
- exe "silent !".g:GetLatestVimScripts_mv." ".shellescape("plugin/".pname)." ".tgtdir
+ exe "silent !".g:GetLatestVimScripts_mv." ".shellescape("plugin/".pname,1)." ".tgtdir
endif

" helptags step
diff --git a/runtime/autoload/rust.vim b/runtime/autoload/rust.vim
index 5ccbf4b38..6510f23be 100644
--- a/runtime/autoload/rust.vim
+++ b/runtime/autoload/rust.vim
@@ -1,5 +1,6 @@
" Description: Helper functions for Rust commands/mappings
" Last Modified: 2023-09-11
+" 2026 May 20 by Vim project: use correct shellescape() with ! command
" For bugs, patches and license go to https://github.com/rust-lang/rust.vim

function! rust#Load()
@@ -125,7 +126,7 @@ function! s:Run(dict, rustc_args, args)
echohl None
endif
if !v:shell_error
- exe '!' . shellescape(exepath) . " " . join(map(a:args, 'shellescape(v:val)'))
+ exe '!' . shellescape(exepath,1) . " " . join(map(a:args, 'shellescape(v:val,1)'))
endif
endfunction

diff --git a/runtime/autoload/vimball.vim b/runtime/autoload/vimball.vim
index 3afd8e6c0..352e94d02 100644
--- a/runtime/autoload/vimball.vim
+++ b/runtime/autoload/vimball.vim
@@ -1,10 +1,9 @@
" vimball.vim : construct a file containing both paths and files
" Maintainer: This runtime file is looking for a new maintainer.
" Original Author: Charles E. Campbell
-" Date: Apr 16, 2026
+" Date: May 20, 2026
" Version: 37 (with modifications from the Vim Project)
" GetLatestVimScripts: 1502 1 :AutoInstall: vimball.vim
-" Last Change:
" Copyright: (c) 2004-2011 by Charles E. Campbell
" The VIM LICENSE applies to Vimball.vim, and Vimball.txt
" (see |copyright|) except use "Vimball" instead of "Vim".
@@ -427,7 +426,7 @@ fun! vimball#Decompress(fname,...)
" decompression:
if expand("%") =~ '.*\.gz' && executable("gunzip")
" handle *.gz with gunzip
- silent exe "!gunzip ".shellescape(a:fname)
+ silent exe "!gunzip ".shellescape(a:fname,1)
if v:shell_error != 0
call vimball#ShowMesg(s:WARNING,"(vimball#Decompress) gunzip may have failed with <".a:fname.">")
endif
@@ -437,7 +436,7 @@ fun! vimball#Decompress(fname,...)

elseif expand("%") =~ '.*\.gz' && executable("gzip")
" handle *.gz with gzip -d
- silent exe "!gzip -d ".shellescape(a:fname)
+ silent exe "!gzip -d ".shellescape(a:fname,1)
if v:shell_error != 0
call vimball#ShowMesg(s:WARNING,'(vimball#Decompress) "gzip -d" may have failed with <'.a:fname.">")
endif
@@ -447,7 +446,7 @@ fun! vimball#Decompress(fname,...)

elseif expand("%") =~ '.*\.bz2' && executable("bunzip2")
" handle *.bz2 with bunzip2
- silent exe "!bunzip2 ".shellescape(a:fname)
+ silent exe "!bunzip2 ".shellescape(a:fname,1)
if v:shell_error != 0
call vimball#ShowMesg(s:WARNING,"(vimball#Decompress) bunzip2 may have failed with <".a:fname.">")
endif
@@ -457,7 +456,7 @@ fun! vimball#Decompress(fname,...)

elseif expand("%") =~ '.*\.bz2' && executable("bzip2")
" handle *.bz2 with bzip2 -d
- silent exe "!bzip2 -d ".shellescape(a:fname)
+ silent exe "!bzip2 -d ".shellescape(a:fname,1)
if v:shell_error != 0
call vimball#ShowMesg(s:WARNING,'(vimball#Decompress) "bzip2 -d" may have failed with <'.a:fname.">")
endif
@@ -467,7 +466,7 @@ fun! vimball#Decompress(fname,...)

elseif expand("%") =~ '.*\.bz3' && executable("bunzip3")
" handle *.bz3 with bunzip3
- silent exe "!bunzip3 ".shellescape(a:fname)
+ silent exe "!bunzip3 ".shellescape(a:fname,1)
if v:shell_error != 0
call vimball#ShowMesg(s:WARNING,"(vimball#Decompress) bunzip3 may have failed with <".a:fname.">")
endif
@@ -477,7 +476,7 @@ fun! vimball#Decompress(fname,...)

elseif expand("%") =~ '.*\.bz3' && executable("bzip3")
" handle *.bz3 with bzip3 -d
- silent exe "!bzip3 -d ".shellescape(a:fname)
+ silent exe "!bzip3 -d ".shellescape(a:fname,1)
if v:shell_error != 0
call vimball#ShowMesg(s:WARNING,'(vimball#Decompress) "bzip3 -d" may have failed with <'.a:fname.">")
endif
@@ -487,7 +486,7 @@ fun! vimball#Decompress(fname,...)

elseif expand("%") =~ '.*\.zip' && executable("unzip")
" handle *.zip with unzip
- silent exe "!unzip ".shellescape(a:fname)
+ silent exe "!unzip ".shellescape(a:fname,1)
if v:shell_error != 0
call vimball#ShowMesg(s:WARNING,"(vimball#Decompress) unzip may have failed with <".a:fname.">")
endif
Reply all
Reply to author
Forward
0 new messages