To: vim_dev@googlegroups.com Subject: Patch 8.2.0633 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.0633 Problem: Crash when using null partial in filter(). Solution: Fix crash. Add more tests. (Yegappan Lakshmanan, closes #5976) Files: src/eval.c, src/testdir/test_blob.vim, src/testdir/test_channel.vim, src/testdir/test_eval_stuff.vim, src/testdir/test_execute_func.vim, src/testdir/test_expr.vim, src/testdir/test_filter_map.vim, src/testdir/test_fold.vim, src/testdir/test_functions.vim, src/testdir/test_let.vim, src/testdir/test_listdict.vim, src/testdir/test_partial.vim, src/testdir/test_usercommands.vim *** ../vim-8.2.0632/src/eval.c 2020-04-23 22:16:49.763270683 +0200 --- src/eval.c 2020-04-24 22:40:46.196359688 +0200 *************** *** 241,246 **** --- 241,249 ---- { partial_T *partial = expr->vval.v_partial; + if (partial == NULL) + return FAIL; + if (partial->pt_func != NULL && partial->pt_func->uf_dfunc_idx >= 0) { if (call_def_function(partial->pt_func, argc, argv, rettv) == FAIL) *************** *** 6416,6423 **** && typ1->vval.v_partial == NULL) || (typ2->v_type == VAR_PARTIAL && typ2->vval.v_partial == NULL)) ! // when a partial is NULL assume not equal ! n1 = FALSE; else if (type_is) { if (typ1->v_type == VAR_FUNC && typ2->v_type == VAR_FUNC) --- 6419,6427 ---- && typ1->vval.v_partial == NULL) || (typ2->v_type == VAR_PARTIAL && typ2->vval.v_partial == NULL)) ! // When both partials are NULL, then they are equal. ! // Otherwise they are not equal. ! n1 = (typ1->vval.v_partial == typ2->vval.v_partial); else if (type_is) { if (typ1->v_type == VAR_FUNC && typ2->v_type == VAR_FUNC) *** ../vim-8.2.0632/src/testdir/test_blob.vim 2020-04-23 13:37:59.494978699 +0200 --- src/testdir/test_blob.vim 2020-04-24 22:40:46.196359688 +0200 *************** *** 142,147 **** --- 142,148 ---- let b2 = b1[:] call assert_true(b1 == b2) call assert_false(b1 is b2) + call assert_true(b1 isnot b2) call assert_fails('let x = b1 > b2') call assert_fails('let x = b1 < b2') *** ../vim-8.2.0632/src/testdir/test_channel.vim 2020-04-21 22:19:26.059486839 +0200 --- src/testdir/test_channel.vim 2020-04-24 22:40:46.196359688 +0200 *************** *** 1203,1208 **** --- 1203,1209 ---- \ 'err_cb': dict.errHandler, \ 'err_mode': 'json'}) call assert_equal("run", job_status(job)) + call test_garbagecollect_now() try let g:Ch_outmsg = '' let g:Ch_errmsg = '' *************** *** 1818,1823 **** --- 1819,1825 ---- let g:out = '' let arg = 'import sys;sys.stdout.write("1\n2\n3")' call job_start([s:python, '-c', arg], {'close_cb': function('s:close_cb')}) + call test_garbagecollect_now() call WaitForAssert({-> assert_equal('123', g:out)}) unlet g:out delfunc s:close_cb *************** *** 1828,1833 **** --- 1830,1836 ---- let arg = 'import os,sys;os.close(1);sys.stderr.write("test\n")' call job_start([s:python, '-c', arg], {'callback': {-> execute('let g:linecount += 1')}}) call WaitForAssert({-> assert_equal(1, g:linecount)}) + call test_garbagecollect_now() unlet g:linecount endfunc *** ../vim-8.2.0632/src/testdir/test_eval_stuff.vim 2020-04-20 16:49:56.705830066 +0200 --- src/testdir/test_eval_stuff.vim 2020-04-24 22:40:46.196359688 +0200 *************** *** 217,223 **** call delete('Xversionscript') endfunc ! func Test_excute_null() call assert_fails('execute test_null_list()', 'E730:') call assert_fails('execute test_null_dict()', 'E731:') call assert_fails('execute test_null_blob()', 'E976:') --- 217,223 ---- call delete('Xversionscript') endfunc ! func Test_execute_cmd_with_null() call assert_fails('execute test_null_list()', 'E730:') call assert_fails('execute test_null_dict()', 'E731:') call assert_fails('execute test_null_blob()', 'E976:') *** ../vim-8.2.0632/src/testdir/test_execute_func.vim 2020-01-30 18:24:46.997204019 +0100 --- src/testdir/test_execute_func.vim 2020-04-24 22:40:46.196359688 +0200 *************** *** 132,138 **** unlet xyz endfunc ! func Test_execute_null() call assert_equal("", execute(test_null_string())) call assert_equal("", execute(test_null_list())) call assert_fails('call execute(test_null_dict())', 'E731:') --- 132,138 ---- unlet xyz endfunc ! func Test_execute_func_with_null() call assert_equal("", execute(test_null_string())) call assert_equal("", execute(test_null_list())) call assert_fails('call execute(test_null_dict())', 'E731:') *************** *** 143,145 **** --- 143,147 ---- call assert_fails('call execute(test_null_channel())', 'E908:') endif endfunc + + " vim: shiftwidth=2 sts=2 expandtab *** ../vim-8.2.0632/src/testdir/test_expr.vim 2020-04-23 13:37:59.494978699 +0200 --- src/testdir/test_expr.vim 2020-04-24 22:40:46.196359688 +0200 *************** *** 1,5 **** --- 1,7 ---- " Tests for expressions. + source check.vim + func Test_equal() let base = {} func base.method() *************** *** 20,25 **** --- 22,29 ---- call assert_false([base.method] == [instance.other]) call assert_fails('echo base.method > instance.method') + call assert_equal(0, test_null_function() == function('min')) + call assert_equal(1, test_null_function() == test_null_function()) endfunc func Test_version() *************** *** 583,586 **** --- 587,610 ---- call assert_fails("let v = -{}", 'E728:') endfunc + " Test for float value comparison + func Test_float_compare() + CheckFeature float + call assert_true(1.2 == 1.2) + call assert_true(1.0 != 1.2) + call assert_true(1.2 > 1.0) + call assert_true(1.2 >= 1.2) + call assert_true(1.0 < 1.2) + call assert_true(1.2 <= 1.2) + call assert_true(+0.0 == -0.0) + " two NaNs (not a number) are not equal + call assert_true(sqrt(-4.01) != (0.0 / 0.0)) + " two inf (infinity) are equal + call assert_true((1.0 / 0) == (2.0 / 0)) + " two -inf (infinity) are equal + call assert_true(-(1.0 / 0) == -(2.0 / 0)) + " +infinity != -infinity + call assert_true((1.0 / 0) != -(2.0 / 0)) + endfunc + " vim: shiftwidth=2 sts=2 expandtab *** ../vim-8.2.0632/src/testdir/test_filter_map.vim 2020-04-23 13:37:59.494978699 +0200 --- src/testdir/test_filter_map.vim 2020-04-24 22:40:46.196359688 +0200 *************** *** 99,104 **** --- 99,108 ---- call assert_fails("let l = filter([1, 2], {})", 'E731:') call assert_equal(0, map(test_null_list(), '"> " .. v:val')) call assert_equal(0, map(test_null_dict(), '"> " .. v:val')) + call assert_equal([1, 2, 3], filter([1, 2, 3], test_null_function())) + call assert_fails("let l = filter([1, 2], function('min'))", 'E118:') + call assert_equal([1, 2, 3], filter([1, 2, 3], test_null_partial())) + call assert_fails("let l = filter([1, 2], {a, b, c -> 1})", 'E119:') endfunc func Test_map_and_modify() *** ../vim-8.2.0632/src/testdir/test_fold.vim 2019-12-13 19:29:22.376873472 +0100 --- src/testdir/test_fold.vim 2020-04-24 22:40:46.196359688 +0200 *************** *** 794,796 **** --- 794,821 ---- bwipe! set foldmethod& endfunc + + " Test for errors in 'foldexpr' + func Test_fold_expr_error() + new + call setline(1, ['one', 'two', 'three']) + + " Return a list from the expression + set foldexpr=[] + set foldmethod=expr + for i in range(3) + call assert_equal(0, foldlevel(i)) + endfor + + " expression error + set foldexpr=[{] + set foldmethod=expr + for i in range(3) + call assert_equal(0, foldlevel(i)) + endfor + + set foldmethod& foldexpr& + close! + endfunc + + " vim: shiftwidth=2 sts=2 expandtab *** ../vim-8.2.0632/src/testdir/test_functions.vim 2020-04-21 22:19:26.059486839 +0200 --- src/testdir/test_functions.vim 2020-04-24 22:40:46.196359688 +0200 *************** *** 1239,1244 **** --- 1239,1246 ---- call assert_equal(0, col([2, '$'])) call assert_equal(0, col([1, 100])) call assert_equal(0, col([1])) + call assert_equal(0, col(test_null_list())) + call assert_fails('let c = col({})', 'E731:') " test for getting the visual start column func T() *** ../vim-8.2.0632/src/testdir/test_let.vim 2020-04-23 13:37:59.494978699 +0200 --- src/testdir/test_let.vim 2020-04-24 22:40:46.196359688 +0200 *************** *** 81,86 **** --- 81,104 ---- let l:Test_Local_Var = {'k' : 5} call assert_match("\nl:Test_Local_Var {'k': 5}", execute('let l:')) call assert_match("v:errors []", execute('let v:')) + + " Test for assigning multiple list items + let l = [1, 2, 3] + let [l[0], l[1]] = [10, 20] + call assert_equal([10, 20, 3], l) + + " Test for errors in conditional expression + call assert_fails('let val = [] ? 1 : 2', 'E745:') + call assert_fails('let val = 1 ? 5+ : 6', 'E121:') + call assert_fails('let val = 1 ? 0 : 5+', 'E15:') + call assert_false(exists('val')) + + " Test for errors in logical operators + let @a = 'if [] || 0 | let val = 2 | endif' + call assert_fails('exe @a', 'E745:') + call assert_fails('call feedkeys(":let val = 0 || []\", "xt")', 'E745:') + call assert_fails('exe "let val = [] && 5"', 'E745:') + call assert_fails('exe "let val = 6 && []"', 'E745:') endfunc func s:set_arg1(a) abort *************** *** 282,294 **** --- 300,319 ---- let d = {'k' : 4} call assert_fails('let d.# = 5', 'E713:') call assert_fails('let d.m += 5', 'E734:') + call assert_fails('let m = d[{]', 'E15:') let l = [1, 2] call assert_fails('let l[2] = 0', 'E684:') call assert_fails('let l[0:1] = [1, 2, 3]', 'E710:') call assert_fails('let l[-2:-3] = [3, 4]', 'E684:') call assert_fails('let l[0:4] = [5, 6]', 'E711:') + call assert_fails('let l -= 2', 'E734:') + call assert_fails('let l += 2', 'E734:') call assert_fails('let g:["a;b"] = 10', 'E461:') call assert_fails('let g:.min = function("max")', 'E704:') + if has('channel') + let ch = test_null_channel() + call assert_fails('let ch += 1', 'E734:') + endif " This test works only when the language is English if v:lang == "C" || v:lang =~ '^[Ee]n' *** ../vim-8.2.0632/src/testdir/test_listdict.vim 2020-04-23 15:46:30.846664908 +0200 --- src/testdir/test_listdict.vim 2020-04-24 22:40:46.196359688 +0200 *************** *** 943,948 **** --- 943,949 ---- call assert_equal(0, uniq(l)) call assert_fails("let k = [] + l", 'E15:') call assert_fails("let k = l + []", 'E15:') + call assert_equal(0, len(copy(test_null_list()))) endfunc " Test for a null dict *************** *** 959,964 **** --- 960,966 ---- call assert_equal('{}', string(d)) call assert_fails('let x = test_null_dict()[10]') call assert_equal({}, {}) + call assert_equal(0, len(copy(test_null_dict()))) endfunc " vim: shiftwidth=2 sts=2 expandtab *** ../vim-8.2.0632/src/testdir/test_partial.vim 2020-03-25 22:23:41.898363595 +0100 --- src/testdir/test_partial.vim 2020-04-24 22:40:46.196359688 +0200 *************** *** 63,68 **** --- 63,69 ---- func Test_partial_dict() let dict = {'name': 'hello'} let Cb = function('MyDictFunc', ["foo", "bar"], dict) + call test_garbagecollect_now() call assert_equal("hello/foo/bar", Cb()) call assert_fails('Cb("xxx")', 'E492:') *************** *** 282,287 **** --- 283,289 ---- let g:ref_job = job_start('echo') let d = {'a': 'b'} call job_setoptions(g:ref_job, {'exit_cb': function('Ignored2', [], d)}) + call test_garbagecollect_now() endif endfunc *************** *** 391,396 **** --- 393,408 ---- call assert_true(F1 isnot# F2) " Different functions call assert_true(F1 isnot# F1d1) " Partial /= non-partial call assert_true(d1.f1 isnot# d1.f1) " handle_subscript creates new partial each time + + " compare two null partials + let N1 = test_null_partial() + let N2 = N1 + call assert_true(N1 is N2) + call assert_true(N1 == N2) + + " compare a partial and a null partial + call assert_false(N1 == F1) + call assert_false(F1 is N1) endfunc " vim: shiftwidth=2 sts=2 expandtab *** ../vim-8.2.0632/src/testdir/test_usercommands.vim 2020-04-23 13:37:59.494978699 +0200 --- src/testdir/test_usercommands.vim 2020-04-24 22:40:46.196359688 +0200 *************** *** 364,369 **** --- 364,373 ---- com! -complete=custom, DoCmd call assert_beeps("call feedkeys(':DoCmd \t', 'tx')") + " custom completion failure with the wrong function + com! -complete=custom,min DoCmd + call assert_fails("call feedkeys(':DoCmd \t', 'tx')", 'E118:') + delcom DoCmd endfunc *** ../vim-8.2.0632/src/version.c 2020-04-24 22:18:57.167585301 +0200 --- src/version.c 2020-04-24 22:42:18.196129011 +0200 *************** *** 748,749 **** --- 748,751 ---- { /* Add new patch number below this line */ + /**/ + 633, /**/ -- hundred-and-one symptoms of being an internet addict: 11. You find yourself typing "com" after every period when using a word processor.com /// 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 ///