diff --git a/runtime/autoload/tar.vim b/runtime/autoload/tar.vim index 1347371b51..3c899f85f6 100644 --- a/runtime/autoload/tar.vim +++ b/runtime/autoload/tar.vim @@ -25,6 +25,7 @@ " 2026 Apr 09 by Vim Project: fix bug with dotted filename (#19930) " 2026 Apr 15 by Vim Project: fix more path traversal issues (#19981) " 2026 Apr 16 by Vim Project: use g:tar_secure in tar#Extract() +" 2026 May 14 by Vim Project: use correct shellescape() call in Vimuntar() " " Contains many ideas from Michael Toren's " @@ -832,9 +833,9 @@ fun! tar#Vimuntar(...) " if necessary, decompress the tarball; then, extract it if tartail =~ '\.tgz' if executable("gunzip") - silent exe "!gunzip ".shellescape(tartail) + silent exe "!gunzip ".shellescape(tartail, 1) elseif executable("gzip") - silent exe "!gzip -d ".shellescape(tartail) + silent exe "!gzip -d ".shellescape(tartail, 1) else echoerr "unable to decompress<".tartail."> on this system" if simplify(curdir) != simplify(tarhome) diff --git a/src/testdir/test_plugin_tar.vim b/src/testdir/test_plugin_tar.vim index 56f25df2ae..e19e5d809c 100644 --- a/src/testdir/test_plugin_tar.vim +++ b/src/testdir/test_plugin_tar.vim @@ -318,3 +318,22 @@ def g:Test_extract_with_dotted_filename() delete('X.txt') bw! enddef + +def g:Test_extract_command_injection() + CheckExecutable gunzip + CheckExecutable touch + var tgz = eval('0z1F8B08087795056A000364756D6D792E74617200EDCE2B12C2300004D01C254' .. + '7480269CE534080A8495BD1DBF3996106C3A08A7ACFACD8157B59A7690BFB4A0FC3707C666E357D' .. + 'E65BC8B5A47CC8A5D61A522EA5B510D3CEBF5ED679197B8CE17CEDB7F9D4C76FBB5F3D000000000' .. + '000000000FCD11D32415E2C00280000') + var dirname = tempname() + + mkdir(dirname, 'R') + var tar = dirname .. "/';%$(touch pwned)'.tgz" + writefile(tgz, tar) + new + exe "e " .. fnameescape(tar) + exe ":Vimuntar " .. dirname + assert_false(filereadable(dirname .. "/pwned")) + bw! +enddef diff --git a/src/version.c b/src/version.c index 8f46a438d9..c98028a80c 100644 --- a/src/version.c +++ b/src/version.c @@ -729,6 +729,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 479, /**/ 478, /**/