]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.1.2079: use-after-free with 'qftf' wiping buffer v9.1.2079
authorChristian Brabandt <cb@256bit.org>
Sun, 11 Jan 2026 19:06:31 +0000 (19:06 +0000)
committerChristian Brabandt <cb@256bit.org>
Sun, 11 Jan 2026 19:06:31 +0000 (19:06 +0000)
Problem:  use-after-free with 'quickfixtextfunc' wiping buffer
          (henices)
Solution: Evaluate 'quickfixtextfunc' with textlock enabled.

closes: #19142

Signed-off-by: Christian Brabandt <cb@256bit.org>
runtime/doc/options.txt
src/quickfix.c
src/testdir/test_quickfix.vim
src/version.c

index aa9cff62d6ee767bf2def17a5fd59c0365dbe631..1dfb8d6f8f3d35f7d26c7b26a0338f182f61cdc3 100644 (file)
@@ -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.
 
index 07e0b7aa1bda76c416a9b2780b602830bf07a16e..87b154dbb6fc7625490fb17a5b86de7cf6d4b4a8 100644 (file)
@@ -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);
     }
 
index 6e939a653fe9806e6e87eaf73b8ae8b2d28aaf99..4c61b6b2ee332e01feb94a0882ad034600b1176c 100644 (file)
@@ -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
index 0e048c40f7fb7afa19844c6911a567c420392e44..c7d7e87e59f2c87457524852f14b7b0e4c7d6afb 100644 (file)
@@ -734,6 +734,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    2079,
 /**/
     2078,
 /**/