To: vim_dev@googlegroups.com Subject: Patch 8.2.2364 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.2364 Problem: Vim9: line break in lambda accesses freed memory. Solution: Make a copy of the return type. (closes #7664) Files: src/userfunc.c, src/testdir/test_vim9_func.vim *** ../vim-8.2.2363/src/userfunc.c 2021-01-15 19:04:28.953912004 +0100 --- src/userfunc.c 2021-01-16 18:07:12.717641120 +0100 *************** *** 539,545 **** char_u *start, *end; int *old_eval_lavars = eval_lavars_used; int eval_lavars = FALSE; ! char_u *tofree = NULL; int equal_arrow = **arg == '('; int white_error = FALSE; --- 539,546 ---- char_u *start, *end; int *old_eval_lavars = eval_lavars_used; int eval_lavars = FALSE; ! char_u *tofree1 = NULL; ! char_u *tofree2 = NULL; int equal_arrow = **arg == '('; int white_error = FALSE; *************** *** 582,587 **** --- 583,595 ---- } *arg = s; + // Skipping over linebreaks may make "ret_type" invalid, make a copy. + if (ret_type != NULL) + { + ret_type = vim_strsave(ret_type); + tofree2 = ret_type; + } + // Set up a flag for checking local variables and arguments. if (evaluate) eval_lavars_used = &eval_lavars; *************** *** 605,611 **** if (evalarg != NULL) { // avoid that the expression gets freed when another line break follows ! tofree = evalarg->eval_tofree; evalarg->eval_tofree = NULL; } --- 613,619 ---- if (evalarg != NULL) { // avoid that the expression gets freed when another line break follows ! tofree1 = evalarg->eval_tofree; evalarg->eval_tofree = NULL; } *************** *** 700,708 **** eval_lavars_used = old_eval_lavars; if (evalarg != NULL && evalarg->eval_tofree == NULL) ! evalarg->eval_tofree = tofree; else ! vim_free(tofree); if (types_optional) ga_clear_strings(&argtypes); return OK; --- 708,717 ---- eval_lavars_used = old_eval_lavars; if (evalarg != NULL && evalarg->eval_tofree == NULL) ! evalarg->eval_tofree = tofree1; else ! vim_free(tofree1); ! vim_free(tofree2); if (types_optional) ga_clear_strings(&argtypes); return OK; *************** *** 715,723 **** vim_free(fp); vim_free(pt); if (evalarg != NULL && evalarg->eval_tofree == NULL) ! evalarg->eval_tofree = tofree; else ! vim_free(tofree); eval_lavars_used = old_eval_lavars; return FAIL; } --- 724,733 ---- vim_free(fp); vim_free(pt); if (evalarg != NULL && evalarg->eval_tofree == NULL) ! evalarg->eval_tofree = tofree1; else ! vim_free(tofree1); ! vim_free(tofree2); eval_lavars_used = old_eval_lavars; return FAIL; } *** ../vim-8.2.2363/src/testdir/test_vim9_func.vim 2021-01-15 19:04:28.953912004 +0100 --- src/testdir/test_vim9_func.vim 2021-01-16 18:05:29.957880721 +0100 *************** *** 1811,1816 **** --- 1811,1828 ---- def Test_line_continuation_in_lambda() Line_continuation_in_lambda()->assert_equal(['D', 'C', 'B', 'A']) + + var lines =<< trim END + vim9script + var res = [{n: 1, m: 2, s: 'xxx'}] + ->mapnew((_, v: dict): string => printf('%d:%d:%s', + v.n, + v.m, + substitute(v.s, '.*', 'yyy', '') + )) + assert_equal(['1:2:yyy'], res) + END + CheckScriptSuccess(lines) enddef def Test_list_lambda() *** ../vim-8.2.2363/src/version.c 2021-01-16 16:52:14.656334823 +0100 --- src/version.c 2021-01-16 18:07:06.097656578 +0100 *************** *** 752,753 **** --- 752,755 ---- { /* Add new patch number below this line */ + /**/ + 2364, /**/ -- hundred-and-one symptoms of being an internet addict: 166. You have been on your computer soo long that you didn't realize you had grandchildren. /// 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 ///