From dd0dd4d78d65cf3a5a75dfceaf0dbf6f4d97501c Mon Sep 17 00:00:00 2001 From: Jan Edmund Lazo Date: Sun, 9 Sep 2018 13:22:10 -0400 Subject: vim-patch:8.0.1115: crash when using foldtextresult() recursively (#8972) Problem: Crash when using foldtextresult() recursively. Solution: Avoid recursive calls. (Yasuhiro Matsumoto, closes vim/vim#2098) https://github.com/vim/vim/commit/495b7dd213e096361e6f15e7aed313c1d63d9d3e --- src/nvim/eval.c | 7 +++++++ src/nvim/testdir/test_fold.vim | 14 ++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 309c0fc062..541a255dcc 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -8872,9 +8872,14 @@ static void f_foldtextresult(typval_T *argvars, typval_T *rettv, FunPtr fptr) char_u buf[FOLD_TEXT_LEN]; foldinfo_T foldinfo; int fold_count; + static bool entered = false; rettv->v_type = VAR_STRING; rettv->vval.v_string = NULL; + if (entered) { + return; // reject recursive use + } + entered = true; linenr_T lnum = tv_get_lnum(argvars); // Treat illegal types and illegal string values for {lnum} the same. if (lnum < 0) { @@ -8888,6 +8893,8 @@ static void f_foldtextresult(typval_T *argvars, typval_T *rettv, FunPtr fptr) } rettv->vval.v_string = text; } + + entered = false; } /* diff --git a/src/nvim/testdir/test_fold.vim b/src/nvim/testdir/test_fold.vim index 6917378890..e7d5a2ae2c 100644 --- a/src/nvim/testdir/test_fold.vim +++ b/src/nvim/testdir/test_fold.vim @@ -278,6 +278,7 @@ func Test_move_folds_around_manual() call assert_equal(0, foldlevel(6)) call assert_equal(9, foldclosedend(7)) call assert_equal([-1, 2, 2, 2, 2, -1, 7, 7, 7, -1], map(range(1, line('$')), 'foldclosed(v:val)')) + %d " Ensure moving around the edges still works. call setline(1, PrepIndent("a") + repeat(["a"], 3) + ["\ta"]) @@ -634,3 +635,16 @@ func Test_fold_move() set fdm& sw& fdl& enew! endfunc + +func Test_foldtext_recursive() + new + call setline(1, ['{{{', 'some text', '}}}']) + setlocal foldenable foldmethod=marker foldtext=foldtextresult(v\:foldstart) + " This was crashing because of endless recursion. + 2foldclose + redraw + call assert_equal(1, foldlevel(2)) + call assert_equal(1, foldclosed(2)) + call assert_equal(3, foldclosedend(2)) + bwipe! +endfunc -- cgit