To: vim_dev@googlegroups.com Subject: Patch 8.2.1749 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.1749 Problem: Vim9: crash when closure fails in nested function. Solution: Handle function returns before dereferencing remaining closures. (closes #7008) Files: src/vim9execute.c, src/testdir/test_vim9_func.vim *** ../vim-8.2.1748/src/vim9execute.c 2020-09-26 15:08:52.881779910 +0200 --- src/vim9execute.c 2020-09-26 19:58:19.629925783 +0200 *************** *** 310,318 **** // Check if any created closure is still in use. for (idx = 0; idx < closure_count; ++idx) { ! partial_T *pt = ((partial_T **)gap->ga_data)[gap->ga_len ! - closure_count + idx]; if (pt->pt_refcount > 1) { int refcount = pt->pt_refcount; --- 310,321 ---- // Check if any created closure is still in use. for (idx = 0; idx < closure_count; ++idx) { ! partial_T *pt; ! int off = gap->ga_len - closure_count + idx; + if (off < 0) + continue; // count is off or already done + pt = ((partial_T **)gap->ga_data)[off]; if (pt->pt_refcount > 1) { int refcount = pt->pt_refcount; *************** *** 2734,2747 **** ret = OK; failed: - // Also deal with closures when failed, they may already be in use - // somewhere. - handle_closure_in_use(&ectx, FALSE); - // When failed need to unwind the call stack. while (ectx.ec_frame_idx != initial_frame_idx) func_return(&ectx); estack_pop(); current_sctx = save_current_sctx; --- 2737,2750 ---- ret = OK; failed: // When failed need to unwind the call stack. while (ectx.ec_frame_idx != initial_frame_idx) func_return(&ectx); + // Deal with any remaining closures, they may be in use somewhere. + if (ectx.ec_funcrefs.ga_len > 0) + handle_closure_in_use(&ectx, FALSE); + estack_pop(); current_sctx = save_current_sctx; *** ../vim-8.2.1748/src/testdir/test_vim9_func.vim 2020-09-23 21:57:16.641934712 +0200 --- src/testdir/test_vim9_func.vim 2020-09-26 19:58:37.289873372 +0200 *************** *** 1370,1375 **** --- 1370,1389 ---- CheckScriptSuccess(lines) enddef + def Test_nested_closure_fails() + let lines =<< trim END + vim9script + def FuncA() + FuncB(0) + enddef + def FuncB(n: number): list + return map([0], {_, v -> n}) + enddef + FuncA() + END + CheckScriptFailure(lines, 'E1012:') + enddef + def Test_sort_return_type() let res: list res = [1, 2, 3]->sort() *** ../vim-8.2.1748/src/version.c 2020-09-26 19:11:35.713467957 +0200 --- src/version.c 2020-09-26 19:34:37.377606859 +0200 *************** *** 752,753 **** --- 752,755 ---- { /* Add new patch number below this line */ + /**/ + 1749, /**/ -- A radioactive cat has eighteen half-lives. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///