From f9186e0c0ebb3f9e47dd1e97382772a0d30e5728 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 26 Aug 2026 15:53:04 +0800 Subject: [PATCH] vim-patch:9.2.1011: [security]: arbitrary Ex command execution during C omni-completion (#41501) Problem: arbitrary Ex command execution during C omni-completion via tag file names (Yazan Balawneh) Solution: Escape the | for all returned tag files Github Security Advisory: https://github.com/vim/vim/security/advisories/GHSA-r77m-8m55-rpr6 https://github.com/vim/vim/commit/331d5d67028505c5b6043603a57d1e8497b922b5 Co-authored-by: Christian Brabandt --- runtime/autoload/ccomplete.vim | 2 +- test/old/testdir/test_plugin_ccomplete.vim | 30 ++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/runtime/autoload/ccomplete.vim b/runtime/autoload/ccomplete.vim index 1928578aa5..b45e240b62 100644 --- a/runtime/autoload/ccomplete.vim +++ b/runtime/autoload/ccomplete.vim @@ -533,7 +533,7 @@ endfunc " member. func s:StructMembers(typename, items, all) " Todo: What about local structures? - let fnames = join(map(tagfiles(), 'escape(v:val, " \\#%")')) + let fnames = join(map(tagfiles(), 'escape(v:val, " \\#%|")')) if fnames == '' return [] endif diff --git a/test/old/testdir/test_plugin_ccomplete.vim b/test/old/testdir/test_plugin_ccomplete.vim index c1754d17c1..92cca050f3 100644 --- a/test/old/testdir/test_plugin_ccomplete.vim +++ b/test/old/testdir/test_plugin_ccomplete.vim @@ -85,4 +85,34 @@ func Test_ccomplete_typeref_completion_still_works() let &tags = save_tags endfunc +" The tags file names from tagfiles() are executed +" via a single vimgrep command and trailing | does +" not cause code execution +func Test_ccomplete_no_exec_via_tagfile_name() + CheckUnix + let dir = "Xcc|&titlestring\t=\t'INJECTED'|ls\t" + call mkdir(dir, 'pR') + let tagsfile = dir .. '/tags' + call writefile(["!_TAG_FILE_SORTED\t0\t/0/", + \ "myvar\tmain.c\t/^x$/;\"\tv\ttyperef:struct:mystruct", + \ "alpha\tmain.c\t/^x$/;\"\tm\tstruct:mystruct", + \ ], tagsfile) + + let save_tags = &tags + let save_title = &titlestring + let &tags = fnamemodify(tagsfile, ':p') + set titlestring=orig + + new + call ccomplete#Complete(1, '') + call ccomplete#Complete(0, 'myvar.x') + + call assert_equal('orig', &titlestring, + \ 'tags file name was executed as an Ex command during omni-completion') + + bwipe! + let &tags = save_tags + let &titlestring = save_title +endfunc + " vim: shiftwidth=2 sts=2 expandtab