]> granicus.if.org Git - vim/commitdiff
patch 8.2.0634: crash with null partial and blob v8.2.0634
authorBram Moolenaar <Bram@vim.org>
Sat, 25 Apr 2020 13:24:44 +0000 (15:24 +0200)
committerBram Moolenaar <Bram@vim.org>
Sat, 25 Apr 2020 13:24:44 +0000 (15:24 +0200)
Problem:    Crash with null partial and blob.
Solution:   Check for NULL pointer.  Add more tests. (Yegappan Lakshmanan,
            closes #5984)

20 files changed:
src/eval.c
src/list.c
src/testdir/test_blob.vim
src/testdir/test_bufwintabinfo.vim
src/testdir/test_cd.vim
src/testdir/test_channel.vim
src/testdir/test_cursor_func.vim
src/testdir/test_eval_stuff.vim
src/testdir/test_expr.vim
src/testdir/test_filter_map.vim
src/testdir/test_fnamemodify.vim
src/testdir/test_functions.vim
src/testdir/test_getvar.vim
src/testdir/test_listdict.vim
src/testdir/test_messages.vim
src/testdir/test_partial.vim
src/testdir/test_quickfix.vim
src/testdir/test_tabpage.vim
src/testdir/test_vimscript.vim
src/version.c

index 659588f1d7316126726e651204ef4c1c45340069..4bd45e9ceb22a407b82d0ee249407648a9ad1d14 100644 (file)
@@ -3682,7 +3682,9 @@ partial_name(partial_T *pt)
 {
     if (pt->pt_name != NULL)
        return pt->pt_name;
-    return pt->pt_func->uf_name;
+    if (pt->pt_func != NULL)
+       return pt->pt_func->uf_name;
+    return (char_u *)"";
 }
 
     static void
index dfd370b544e27ed87e147cd95ce89273a655906b..eb76cc6831c9287d154fa5260f27a1d2abc7a752 100644 (file)
@@ -2167,6 +2167,9 @@ f_insert(typval_T *argvars, typval_T *rettv)
        int         val, len;
        char_u      *p;
 
+       if (argvars[0].vval.v_blob == NULL)
+           return;
+
        len = blob_len(argvars[0].vval.v_blob);
        if (argvars[2].v_type != VAR_UNKNOWN)
        {
index 3c1510136a99d9129948b952ea15116a5c4d41c4..46b7b0227f5fd989b4ffea4eff389238518567a3 100644 (file)
@@ -33,6 +33,7 @@ func Test_blob_create()
   call assert_fails('let b = 0z.')
   call assert_fails('let b = 0z001122.')
   call assert_fails('call get("", 1)', 'E896:')
+  call assert_equal(0, len(test_null_blob()))
 endfunc
 
 " assignment to a blob
@@ -100,6 +101,7 @@ func Test_blob_get()
   call assert_equal(999, get(b, 5, 999))
   call assert_equal(-1, get(b, -8))
   call assert_equal(999, get(b, -8, 999))
+  call assert_equal(10, get(test_null_blob(), 2, 10))
 
   call assert_equal(0x00, b[0])
   call assert_equal(0x22, b[2])
@@ -117,6 +119,7 @@ func Test_blob_to_string()
   call assert_equal('0z00112233', string(b))
   call remove(b, 0, 3)
   call assert_equal('0z', string(b))
+  call assert_equal('0z', string(test_null_blob()))
 endfunc
 
 func Test_blob_compare()
@@ -251,6 +254,7 @@ func Test_blob_func_remove()
   call assert_fails("call remove(b, 3, 2)", 'E979:')
   call assert_fails("call remove(1, 0)", 'E896:')
   call assert_fails("call remove(b, b)", 'E974:')
+  call assert_fails("call remove(test_null_blob(), 1, 2)", 'E979:')
 endfunc
 
 func Test_blob_read_write()
@@ -313,6 +317,7 @@ func Test_blob_insert()
   call assert_fails('call insert(b, 0, -20)', 'E475:')
   call assert_fails('call insert(b, 0, 20)', 'E475:')
   call assert_fails('call insert(b, [])', 'E745:')
+  call assert_equal(0, insert(test_null_blob(), 0x33))
 endfunc
 
 func Test_blob_reverse()
@@ -320,6 +325,7 @@ func Test_blob_reverse()
   call assert_equal(0zBEADDE, reverse(0zDEADBE))
   call assert_equal(0zADDE, reverse(0zDEAD))
   call assert_equal(0zDE, reverse(0zDE))
+  call assert_equal(0z, reverse(test_null_blob()))
 endfunc
 
 func Test_blob_json_encode()
index d61670b6701a0af0cd9a1129dcc7506f34defb49..43d0473a141ec031561d6105a0d6f5db7e308798 100644 (file)
@@ -42,6 +42,7 @@ func Test_getbufwintabinfo()
     sign undefine Mark
     enew!
   endif
+  call assert_notequal([], getbufinfo(test_null_dict()))
 
   only
   let w1_id = win_getid()
index e5c119e22edbf3e4be099c529b4e87bb462fb3d1..da9ef0830fb223188f3bc634fb2baee29fd7b140 100644 (file)
@@ -119,6 +119,7 @@ func Test_chdir_func()
   call assert_equal("", d)
   " Should not crash
   call chdir(d)
+  call assert_equal('', chdir([]))
 
   only | tabonly
   call chdir(topdir)
index 9c51c640d6eda640ead7a8077e4b8a3c0d7f5bef..4ba552bdbe92dd0d52ceb43bc03b9742460feca4 100644 (file)
@@ -1139,6 +1139,8 @@ func Test_pipe_null()
   call assert_equal("run", job_status(job))
   call assert_equal('channel fail', string(job_getchannel(job)))
   call assert_equal('fail', ch_status(job))
+  call assert_equal('no process', string(test_null_job()))
+  call assert_equal('channel fail', string(test_null_channel()))
   call job_stop(job)
 endfunc
 
@@ -1706,6 +1708,7 @@ func Test_partial_in_channel_cycle()
   let d.a = function('string', [d])
   try
     let d.b = ch_open('nowhere:123', {'close_cb': d.a})
+    call test_garbagecollect_now()
   catch
     call assert_exception('E901:')
   endtry
@@ -1893,6 +1896,7 @@ function Ch_test_close_lambda(port)
   endif
   let g:Ch_close_ret = ''
   call ch_setoptions(handle, {'close_cb': {ch -> execute("let g:Ch_close_ret = 'closed'")}})
+  call test_garbagecollect_now()
 
   call assert_equal('', ch_evalexpr(handle, 'close me'))
   call WaitForAssert({-> assert_equal('closed', g:Ch_close_ret)})
index 7a17958335b3a46623a7a9b48eba96d5dd6a6ff2..0ddfcdadfd4eeab564e8e913eded7408875bbe85 100644 (file)
@@ -2,6 +2,7 @@
 
 func Test_wrong_arguments()
   call assert_fails('call cursor(1. 3)', 'E474:')
+  call assert_fails('call cursor(test_null_list())', 'E474:')
 endfunc
 
 func Test_move_cursor()
index cd9611c461066d48232eeacb426cb0ca592fdf0f..28350bb3e2aba17558d7a7248a2abe02b7ab27fd 100644 (file)
@@ -41,6 +41,9 @@ func Test_mkdir_p()
   call assert_fails('call mkdir("Xfile", "p")', 'E739')
   call delete('Xfile')
   call delete('Xmkdir', 'rf')
+  call assert_equal(0, mkdir(test_null_string()))
+  call assert_fails('call mkdir([])', 'E730')
+  call assert_fails('call mkdir("abc", [], [])', 'E745')
 endfunc
 
 func Test_line_continuation()
@@ -223,6 +226,7 @@ func Test_execute_cmd_with_null()
   call assert_fails('execute test_null_blob()', 'E976:')
   execute test_null_string()
   call assert_fails('execute test_null_partial()', 'E729:')
+  call assert_fails('execute test_unknown()', 'E908:')
   if has('job')
     call assert_fails('execute test_null_job()', 'E908:')
     call assert_fails('execute test_null_channel()', 'E908:')
index c8b5464f41167714b1cdf6f9450d6ff6b5154ca1..5fc502df8126f854f07d831c344970674bd615cb 100644 (file)
@@ -24,6 +24,7 @@ func Test_equal()
   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())
+  call assert_fails('eval 10 == test_unknown()', 'E685:')
 endfunc
 
 func Test_version()
@@ -100,7 +101,7 @@ func Test_loop_over_null_list()
   endfor
 endfunc
 
-func Test_set_reg_null_list()
+func Test_setreg_null_list()
   call setreg('x', test_null_list())
 endfunc
 
index 0e47badc206dbb806f945d91197e11884c87f0ff..0f58685c60d12a33f04933330c0ee24ab857238e 100644 (file)
@@ -97,6 +97,8 @@ func Test_map_filter_fails()
   call assert_fails("let l = filter([1, 2, 3], '{}')", 'E728:')
   call assert_fails("let l = filter({'k' : 10}, '{}')", 'E728:')
   call assert_fails("let l = filter([1, 2], {})", 'E731:')
+  call assert_equal(0, filter(test_null_list(), 0))
+  call assert_equal(0, filter(test_null_dict(), 0))
   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()))
index b35f1534028b360ac5289560681d559c37821aa0..b90d232f95b3cddf45e8ac0903a0667c020c9126 100644 (file)
@@ -86,4 +86,8 @@ func Test_fnamemodify_er()
   " :e never includes the whole filename, so "a.b":e:e:e --> "b"
   call assert_equal('b.c', fnamemodify('a.b.c.d.e', ':r:r:e:e:e'))
   call assert_equal('b.c', fnamemodify('a.b.c.d.e', ':r:r:e:e:e:e'))
+
+  call assert_equal('', fnamemodify(test_null_string(), test_null_string()))
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
index 029ea5b9780acf0feb0a43515dabb079b43fdc57..a0807ade7af0e7e6a8b36e9b797675b64ca3f9b2 100644 (file)
@@ -480,6 +480,7 @@ func Test_pathshorten()
   call assert_equal('~.f/bar', pathshorten('~.foo/bar'))
   call assert_equal('.~f/bar', pathshorten('.~foo/bar'))
   call assert_equal('~/f/bar', pathshorten('~/foo/bar'))
+  call assert_fails('call pathshorten([])', 'E730:')
 endfunc
 
 func Test_strpart()
@@ -970,6 +971,7 @@ func Test_matchstrpos()
   call assert_equal(['', -1, -1], matchstrpos('testing', 'ing', 8))
   call assert_equal(['ing', 1, 4, 7], matchstrpos(['vim', 'testing', 'execute'], 'ing'))
   call assert_equal(['', -1, -1, -1], matchstrpos(['vim', 'testing', 'execute'], 'img'))
+  call assert_equal(['', -1, -1], matchstrpos(test_null_list(), '\a'))
 endfunc
 
 func Test_nextnonblank_prevnonblank()
@@ -1222,6 +1224,7 @@ func Test_hlexists()
   syntax off
 endfunc
 
+" Test for the col() function
 func Test_col()
   new
   call setline(1, 'abcdef')
@@ -1332,6 +1335,7 @@ func Test_inputlist()
   call assert_equal(-2, c)
 
   call assert_fails('call inputlist("")', 'E686:')
+  call assert_fails('call inputlist(test_null_list())', 'E686:')
 endfunc
 
 func Test_balloon_show()
@@ -2227,6 +2231,16 @@ func Test_echoraw()
   call delete('XTest_echoraw')
 endfunc
 
+" Test for echo highlighting
+func Test_echohl()
+  echohl Search
+  echo 'Vim'
+  call assert_equal('Vim', Screenline(&lines))
+  " TODO: How to check the highlight group used by echohl?
+  " ScreenAttrs() returns all zeros.
+  echohl None
+endfunc
+
 " Test for the eval() function
 func Test_eval()
   call assert_fails("call eval('5 a')", 'E488:')
@@ -2258,7 +2272,27 @@ func Test_getcurpos_setpos()
   call setpos('.', sp)
   normal jyl
   call assert_equal('6', @")
+  call assert_equal(-1, setpos('.', test_null_list()))
+  call assert_equal(-1, setpos('.', {}))
   close!
 endfunc
 
+" Test for glob()
+func Test_glob()
+  call assert_equal('', glob(test_null_string()))
+  call assert_equal('', globpath(test_null_string(), test_null_string()))
+endfunc
+
+" Test for browse()
+func Test_browse()
+  CheckFeature browse
+  call assert_fails('call browse([], "open", "x", "a.c")', 'E745:')
+endfunc
+
+" Test for browsedir()
+func Test_browsedir()
+  CheckFeature browse
+  call assert_fails('call browsedir("open", [])', 'E730:')
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
index 5da5991361283d076fb195312331bf4a5acb0155..7ced44d07c4fce5cbfd57dd31be9e041c29f8c8c 100644 (file)
@@ -142,6 +142,11 @@ func Test_get_func()
   call assert_equal({'func has': 'no dict'}, get(l:F, 'dict', {'func has': 'no dict'}))
   call assert_equal(0, get(l:F, 'dict'))
   call assert_equal([], get(l:F, 'args'))
+  let NF = test_null_function()
+  call assert_equal('', get(NF, 'name'))
+  call assert_equal(NF, get(NF, 'func'))
+  call assert_equal(0, get(NF, 'dict'))
+  call assert_equal([], get(NF, 'args'))
 endfunc
 
 " get({partial}, {what} [, {default}]) - in test_partial.vim
index 87d7a2c94ea6d794556781a056b0a303110ad144..1dea4a88c51aa45bbcd7f5e6f0ea7994e36e521d 100644 (file)
@@ -724,6 +724,7 @@ func Test_listdict_compare_complex()
   call assert_true(dict4 == dict4copy)
 endfunc
 
+" Test for extending lists and dictionaries
 func Test_listdict_extend()
   " Test extend() with lists
 
@@ -926,6 +927,8 @@ func Test_listdict_index()
   call assert_fails("let l[1.1] = 4", 'E806:')
   call assert_fails("let l[:i] = [4, 5]", 'E121:')
   call assert_fails("let l[:3.2] = [4, 5]", 'E806:')
+  let t = test_unknown()
+  call assert_fails("echo t[0]", 'E685:')
 endfunc
 
 " Test for a null list
@@ -943,7 +946,23 @@ func Test_null_list()
   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())))
+  call assert_equal(0, len(copy(l)))
+  call assert_equal(0, count(l, 5))
+  call assert_equal([], deepcopy(l))
+  call assert_equal(5, get(l, 2, 5))
+  call assert_equal(-1, index(l, 2, 5))
+  call assert_equal(0, insert(l, 2, -1))
+  call assert_equal(0, min(l))
+  call assert_equal(0, max(l))
+  call assert_equal(0, remove(l, 0, 2))
+  call assert_equal([], repeat(l, 2))
+  call assert_equal(0, reverse(l))
+  call assert_equal(0, sort(l))
+  call assert_equal('[]', string(l))
+  call assert_equal(0, extend(l, l, 0))
+  lockvar l
+  call assert_equal(1, islocked('l'))
+  unlockvar l
 endfunc
 
 " Test for a null dict
@@ -958,9 +977,20 @@ func Test_null_dict()
   call assert_equal(0, values(d))
   call assert_false(has_key(d, 'k'))
   call assert_equal('{}', string(d))
-  call assert_fails('let x = test_null_dict()[10]')
+  call assert_fails('let x = d[10]')
   call assert_equal({}, {})
-  call assert_equal(0, len(copy(test_null_dict())))
+  call assert_equal(0, len(copy(d)))
+  call assert_equal(0, count(d, 'k'))
+  call assert_equal({}, deepcopy(d))
+  call assert_equal(20, get(d, 'k', 20))
+  call assert_equal(0, min(d))
+  call assert_equal(0, max(d))
+  call assert_equal(0, remove(d, 'k'))
+  call assert_equal('{}', string(d))
+  call assert_equal(0, extend(d, d, 0))
+  lockvar d
+  call assert_equal(1, islocked('d'))
+  unlockvar d
 endfunc
 
 " vim: shiftwidth=2 sts=2 expandtab
index ac91aa097b202af42fbbc9bc75670cf3d1dcd41b..84808efa09576b03253f9e8bccdd85c76469d19f 100644 (file)
@@ -305,9 +305,12 @@ func Test_null()
   echom test_null_dict()
   echom test_null_blob()
   echom test_null_string()
+  echom test_null_function()
   echom test_null_partial()
   if has('job')
     echom test_null_job()
     echom test_null_channel()
   endif
 endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
index 5b273db230787231b3d574f0ffde56107be3a05a..2fad7b2892a3818081767d2d752d4b983f989f96 100644 (file)
@@ -194,6 +194,8 @@ func Test_partial_string()
   call assert_equal("function('MyFunc', {'one': 1})", string(F))
   let F = function('MyFunc', ['foo'], d)
   call assert_equal("function('MyFunc', ['foo'], {'one': 1})", string(F))
+  call assert_equal("function('')", string(test_null_function()))
+  call assert_equal("function('')", string(test_null_partial()))
 endfunc
 
 func Test_func_unref()
index c1b50631beabd8ec6dd871e9a298bdd6ff6e2683..cfd9a35b7d32383ca747f41cafe73cad8b77b449 100644 (file)
@@ -2158,6 +2158,18 @@ func Xproperty_tests(cchar)
     call g:Xsetlist([], 'a', {'context':246})
     let d = g:Xgetlist({'context':1})
     call assert_equal(246, d.context)
+    " set other Vim data types as context
+    call g:Xsetlist([], 'a', {'context' : test_null_blob()})
+    if has('channel')
+      call g:Xsetlist([], 'a', {'context' : test_null_channel()})
+    endif
+    if has('job')
+      call g:Xsetlist([], 'a', {'context' : test_null_job()})
+    endif
+    call g:Xsetlist([], 'a', {'context' : test_null_function()})
+    call g:Xsetlist([], 'a', {'context' : test_null_partial()})
+    call g:Xsetlist([], 'a', {'context' : ''})
+    call test_garbagecollect_now()
     if a:cchar == 'l'
        " Test for copying context across two different location lists
        new | only
index 35c9fd0eab69fe2f4598a8dc52f9d35bbe3989d9..80cc8e55918ef948333a190afa8e3dda2fe4e3af 100644 (file)
@@ -130,6 +130,8 @@ function Test_tabpage()
   1tabmove
   call assert_equal(2, tabpagenr())
 
+  call assert_fails('let t = tabpagenr("#")', 'E15:')
+  call assert_equal(0, tabpagewinnr(-1))
   call assert_fails("99tabmove", 'E16:')
   call assert_fails("+99tabmove", 'E16:')
   call assert_fails("-99tabmove", 'E16:')
index 439114d19b3b3182d1aeed659d27fff3fc970ab6..805787a7abe0f6098d06a8a73a0cee3debad85a0 100644 (file)
@@ -1164,6 +1164,18 @@ func Test_type()
     call assert_equal(v:t_bool, type(v:true))
     call assert_equal(v:t_none, type(v:none))
     call assert_equal(v:t_none, type(v:null))
+    call assert_equal(v:t_string, type(test_null_string()))
+    call assert_equal(v:t_func, type(test_null_function()))
+    call assert_equal(v:t_func, type(test_null_partial()))
+    call assert_equal(v:t_list, type(test_null_list()))
+    call assert_equal(v:t_dict, type(test_null_dict()))
+    if has('job')
+      call assert_equal(v:t_job, type(test_null_job()))
+    endif
+    if has('channel')
+      call assert_equal(v:t_channel, type(test_null_channel()))
+    endif
+    call assert_equal(v:t_blob, type(test_null_blob()))
 
     call assert_fails("call type(test_void())", 'E685:')
     call assert_fails("call type(test_unknown())", 'E685:')
index 81f5a33899249ce640678490a767a53230f1d4ef..b05d3d884f9f3335758efa1bb776bc1c1c3b48bd 100644 (file)
@@ -746,6 +746,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    634,
 /**/
     633,
 /**/