From: Christian Brabandt Date: Sun, 11 Jan 2026 19:06:31 +0000 (+0000) Subject: patch 9.1.2079: use-after-free with 'qftf' wiping buffer X-Git-Tag: v9.1.2079^0 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=300ea1133fba310ae8acd7fadc3ab3cc24e8402f;p=thirdparty%2Fvim.git patch 9.1.2079: use-after-free with 'qftf' wiping buffer Problem: use-after-free with 'quickfixtextfunc' wiping buffer (henices) Solution: Evaluate 'quickfixtextfunc' with textlock enabled. closes: #19142 Signed-off-by: Christian Brabandt --- diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index aa9cff62d6..1dfb8d6f8f 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -6973,6 +6973,9 @@ A jump table for the options with a short description can be found at |Q_op|. |lambda| or a |Funcref|. See |option-value-function| for more information. + It is not allowed to change text or jump to another window while + evaluating 'qftf' |textlock|. + This option cannot be set from a |modeline| or in the |sandbox|, for security reasons. diff --git a/src/quickfix.c b/src/quickfix.c index 07e0b7aa1b..87b154dbb6 100644 --- a/src/quickfix.c +++ b/src/quickfix.c @@ -5097,6 +5097,7 @@ call_qftf_func(qf_list_T *qfl, int qf_winid, long start_idx, long end_idx) args[0].vval.v_dict = d; qftf_list = NULL; + textlock++; if (call_callback(cb, 0, &rettv, 1, args) != FAIL) { if (rettv.v_type == VAR_LIST) @@ -5106,6 +5107,7 @@ call_qftf_func(qf_list_T *qfl, int qf_winid, long start_idx, long end_idx) } clear_tv(&rettv); } + textlock--; dict_unref(d); } diff --git a/src/testdir/test_quickfix.vim b/src/testdir/test_quickfix.vim index 6e939a653f..4c61b6b2ee 100644 --- a/src/testdir/test_quickfix.vim +++ b/src/testdir/test_quickfix.vim @@ -6969,4 +6969,27 @@ func Test_quickfix_restore_current_win() bw! Xb endfunc +func Test_quickfixtextfunc_wipes_buffer() + let g:crash="" + new + fu QFexpr(dummy) + bw + endfu + try + set quickfixtextfunc=QFexpr + lad "['0:4:e']" + lw + catch /^Vim\%((\S\+)\)\=:E565:/ + let g:crash='caught' + endtry + " close location list window + bw + delfunc QFexpr + set quickfixtextfunc= + call assert_equal('caught', g:crash) + unlet g:crash + " close the newly opened window + bw +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/version.c b/src/version.c index 0e048c40f7..c7d7e87e59 100644 --- a/src/version.c +++ b/src/version.c @@ -734,6 +734,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2079, /**/ 2078, /**/