From 61eddb3fe7b01fb904bb9a87a78ef1239c01eb2e Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sun, 24 May 2026 09:29:50 +0800 Subject: [PATCH] vim-patch:9.2.0523: tests: no test for using shellescape() in combination with :! (#39972) Problem: tests: no test for using shellescape() in combination with :! Solution: Add a test that checks runtime files for using wrong combination of shellescape() with ! ex command This has lead to a few security relevant issues, so add a test that checks all runtime files for any ! followed by a shellescape() that does not use the {special} arg. related: Commit: 3fb5e58fbc63d86a3e65f1a141b0d67af2 (patch 9.2.0479: [security]: runtime(tar): command injection in tar plugin) closes: vim/vim#20286 Supported by AI https://github.com/vim/vim/commit/fccc2adc98c3d6664f1f2d8ddab17b096e647986 Co-authored-by: Christian Brabandt --- runtime/autoload/context.vim | 2 +- test/old/testdir/test_codestyle.vim | 39 +++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/runtime/autoload/context.vim b/runtime/autoload/context.vim index 254d710c01..88db3ee0f2 100644 --- a/runtime/autoload/context.vim +++ b/runtime/autoload/context.vim @@ -117,7 +117,7 @@ else " No jobs endfunction function! s:typeset(path) - execute '!' . context#command() . ' ' . shellescape(fnamemodify(a:path, ":t")) + execute '!' . context#command() . ' ' . shellescape(fnamemodify(a:path, ":t"), 1) call call(get(b:, 'context_callback', get(g:, 'context_callback', 'context#callback')), \ [a:path, 0, v:shell_error]) endfunction diff --git a/test/old/testdir/test_codestyle.vim b/test/old/testdir/test_codestyle.vim index a0cebf76d1..e88b5e3790 100644 --- a/test/old/testdir/test_codestyle.vim +++ b/test/old/testdir/test_codestyle.vim @@ -6,6 +6,22 @@ func s:ReportError(fname, lnum, msg) endif endfunc +func s:PerformCheck(fname, pattern, msg, skip) + let prev_lnum = 1 + let lnum = 1 + while (lnum > 0) + call cursor(lnum, 1) + let lnum = search(a:pattern, 'W', 0, 0, a:skip) + if (prev_lnum == lnum) + break + endif + let prev_lnum = lnum + if (lnum > 0) + call s:ReportError(a:fname, lnum, a:msg) + endif + endwhile +endfunc + func Test_test_files() for fname in glob('*.vim', 0, 1) let g:ignoreSwapExists = 'e' @@ -99,4 +115,27 @@ func Test_help_files() endfunc +func Test_runtime_wrong_shellescape() + " Check that shellescape() is called with the {special} argument (a second, + " non-zero argument) when its result is used in a ":!" ex command. + " This could cause code injection! + let pattern = '\