diff options
| -rw-r--r-- | src/nvim/quickfix.c | 9 | ||||
| -rw-r--r-- | src/nvim/testdir/test_quickfix.vim | 47 | 
2 files changed, 53 insertions, 3 deletions
| diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 3608a41a6e..c5d03e73f1 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -4278,7 +4278,10 @@ static int qf_set_properties(qf_info_T *qi, dict_T *what, int action)    if ((di = tv_dict_find(what, S_LEN("nr"))) != NULL) {      // Use the specified quickfix/location list      if (di->di_tv.v_type == VAR_NUMBER) { -      qf_idx = (int)di->di_tv.vval.v_number - 1; +      // for zero use the current list +      if (di->di_tv.vval.v_number != 0) { +        qf_idx = (int)di->di_tv.vval.v_number - 1; +      }        if (qf_idx < 0 || qf_idx >= qi->qf_listcount) {          return FAIL;        } @@ -4306,11 +4309,11 @@ static int qf_set_properties(qf_info_T *qi, dict_T *what, int action)    }    if ((di = tv_dict_find(what, S_LEN("context"))) != NULL) { -    tv_free(qi->qf_lists[qi->qf_curlist].qf_ctx); +    tv_free(qi->qf_lists[qf_idx].qf_ctx);      typval_T *ctx = xcalloc(1, sizeof(typval_T));      tv_copy(&di->di_tv, ctx); -    qi->qf_lists[qi->qf_curlist].qf_ctx = ctx; +    qi->qf_lists[qf_idx].qf_ctx = ctx;    }    return retval; diff --git a/src/nvim/testdir/test_quickfix.vim b/src/nvim/testdir/test_quickfix.vim index 1d17da31ed..30023dddc9 100644 --- a/src/nvim/testdir/test_quickfix.vim +++ b/src/nvim/testdir/test_quickfix.vim @@ -1786,6 +1786,37 @@ func Xproperty_tests(cchar)  	call setloclist(0, [], 'f')  	call assert_equal({}, getloclist(0, {'context':1}))      endif + +    " Test for changing the context of previous quickfix lists +    call g:Xsetlist([], 'f') +    Xexpr "One" +    Xexpr "Two" +    Xexpr "Three" +    call g:Xsetlist([], ' ', {'context' : [1], 'nr' : 1}) +    call g:Xsetlist([], ' ', {'context' : [2], 'nr' : 2}) +    " Also, check for setting the context using quickfix list number zero. +    call g:Xsetlist([], ' ', {'context' : [3], 'nr' : 0}) +    call test_garbagecollect_now() +    let l = g:Xgetlist({'nr' : 1, 'context' : 1}) +    call assert_equal([1], l.context) +    let l = g:Xgetlist({'nr' : 2, 'context' : 1}) +    call assert_equal([2], l.context) +    let l = g:Xgetlist({'nr' : 3, 'context' : 1}) +    call assert_equal([3], l.context) + +    " Test for changing the context through reference and for garbage +    " collection of quickfix context +    let l = ["red"] +    call g:Xsetlist([], ' ', {'context' : l}) +    call add(l, "blue") +    let x = g:Xgetlist({'context' : 1}) +    call add(x.context, "green") +    call assert_equal(["red", "blue", "green"], l) +    call assert_equal(["red", "blue", "green"], x.context) +    unlet l +    call test_garbagecollect_now() +    let m = g:Xgetlist({'context' : 1}) +    call assert_equal(["red", "blue", "green"], m.context)  endfunc  func Test_qf_property() @@ -2055,3 +2086,19 @@ func Test_qf_free()    call XfreeTests('c')    call XfreeTests('l')  endfunc + +" Test for buffer overflow when parsing lines and adding new entries to +" the quickfix list. +func Test_bufoverflow() +  set efm=%f:%l:%m +  cgetexpr ['File1:100:' . repeat('x', 1025)] + +  set efm=%+GCompiler:\ %.%#,%f:%l:%m +  cgetexpr ['Compiler: ' . repeat('a', 1015), 'File1:10:Hello World'] + +  set efm=%DEntering\ directory\ %f,%f:%l:%m +  cgetexpr ['Entering directory ' . repeat('a', 1006), +	      \ 'File1:10:Hello World'] +  set efm&vim +endfunc + | 
