mirror of
https://github.com/vim/vim.git
synced 2025-09-26 04:04:07 -04:00
patch 7.4.1768
Problem: Arguments of setqflist() are not checked properly. Solution: Add better checks, add a test. (Nikolai Pavlov, Hirohito Higashi, closes #661)
This commit is contained in:
14
src/eval.c
14
src/eval.c
@@ -98,6 +98,7 @@ static char *e_listarg = N_("E686: Argument of %s must be a List");
|
|||||||
static char *e_listdictarg = N_("E712: Argument of %s must be a List or Dictionary");
|
static char *e_listdictarg = N_("E712: Argument of %s must be a List or Dictionary");
|
||||||
static char *e_listreq = N_("E714: List required");
|
static char *e_listreq = N_("E714: List required");
|
||||||
static char *e_dictreq = N_("E715: Dictionary required");
|
static char *e_dictreq = N_("E715: Dictionary required");
|
||||||
|
static char *e_stringreq = N_("E928: String required");
|
||||||
static char *e_toomanyarg = N_("E118: Too many arguments for function: %s");
|
static char *e_toomanyarg = N_("E118: Too many arguments for function: %s");
|
||||||
static char *e_dictkey = N_("E716: Key not present in Dictionary: %s");
|
static char *e_dictkey = N_("E716: Key not present in Dictionary: %s");
|
||||||
static char *e_funcexts = N_("E122: Function %s already exists, add ! to replace it");
|
static char *e_funcexts = N_("E122: Function %s already exists, add ! to replace it");
|
||||||
@@ -18280,8 +18281,9 @@ set_qf_ll_list(
|
|||||||
typval_T *rettv)
|
typval_T *rettv)
|
||||||
{
|
{
|
||||||
#ifdef FEAT_QUICKFIX
|
#ifdef FEAT_QUICKFIX
|
||||||
|
static char *e_invact = N_("E927: Invalid action: '%s'");
|
||||||
char_u *act;
|
char_u *act;
|
||||||
int action = ' ';
|
int action = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
rettv->vval.v_number = -1;
|
rettv->vval.v_number = -1;
|
||||||
@@ -18298,11 +18300,17 @@ set_qf_ll_list(
|
|||||||
act = get_tv_string_chk(action_arg);
|
act = get_tv_string_chk(action_arg);
|
||||||
if (act == NULL)
|
if (act == NULL)
|
||||||
return; /* type error; errmsg already given */
|
return; /* type error; errmsg already given */
|
||||||
if (*act == 'a' || *act == 'r')
|
if ((*act == 'a' || *act == 'r' || *act == ' ') && act[1] == NUL)
|
||||||
action = *act;
|
action = *act;
|
||||||
|
else
|
||||||
|
EMSG2(_(e_invact), act);
|
||||||
}
|
}
|
||||||
|
else if (action_arg->v_type == VAR_UNKNOWN)
|
||||||
|
action = ' ';
|
||||||
|
else
|
||||||
|
EMSG(_(e_stringreq));
|
||||||
|
|
||||||
if (l != NULL && set_errorlist(wp, l, action,
|
if (l != NULL && action && set_errorlist(wp, l, action,
|
||||||
(char_u *)(wp == NULL ? "setqflist()" : "setloclist()")) == OK)
|
(char_u *)(wp == NULL ? "setqflist()" : "setloclist()")) == OK)
|
||||||
rettv->vval.v_number = 0;
|
rettv->vval.v_number = 0;
|
||||||
}
|
}
|
||||||
|
@@ -501,7 +501,7 @@ endfunction
|
|||||||
function Test_locationlist_curwin_was_closed()
|
function Test_locationlist_curwin_was_closed()
|
||||||
augroup testgroup
|
augroup testgroup
|
||||||
au!
|
au!
|
||||||
autocmd BufReadCmd t call R(expand("<amatch>"))
|
autocmd BufReadCmd test_curwin.txt call R(expand("<amatch>"))
|
||||||
augroup END
|
augroup END
|
||||||
|
|
||||||
function! R(n)
|
function! R(n)
|
||||||
@@ -510,7 +510,7 @@ function Test_locationlist_curwin_was_closed()
|
|||||||
|
|
||||||
new
|
new
|
||||||
let q = []
|
let q = []
|
||||||
call add(q, {'filename': 't' })
|
call add(q, {'filename': 'test_curwin.txt' })
|
||||||
call setloclist(0, q)
|
call setloclist(0, q)
|
||||||
call assert_fails('lrewind', 'E924:')
|
call assert_fails('lrewind', 'E924:')
|
||||||
|
|
||||||
@@ -643,14 +643,14 @@ function XquickfixChangedByAutocmd(cchar)
|
|||||||
let Xgetexpr = a:cchar . 'getexpr'
|
let Xgetexpr = a:cchar . 'getexpr'
|
||||||
let Xrewind = a:cchar . 'rewind'
|
let Xrewind = a:cchar . 'rewind'
|
||||||
if a:cchar == 'c'
|
if a:cchar == 'c'
|
||||||
let Xsetlist = 'setqflist('
|
let Xsetlist = function('setqflist')
|
||||||
let ErrorNr = 'E925'
|
let ErrorNr = 'E925'
|
||||||
function! ReadFunc()
|
function! ReadFunc()
|
||||||
colder
|
colder
|
||||||
cgetexpr []
|
cgetexpr []
|
||||||
endfunc
|
endfunc
|
||||||
else
|
else
|
||||||
let Xsetlist = 'setloclist(0,'
|
let Xsetlist = function('setloclist', [0])
|
||||||
let ErrorNr = 'E926'
|
let ErrorNr = 'E926'
|
||||||
function! ReadFunc()
|
function! ReadFunc()
|
||||||
lolder
|
lolder
|
||||||
@@ -660,15 +660,15 @@ function XquickfixChangedByAutocmd(cchar)
|
|||||||
|
|
||||||
augroup testgroup
|
augroup testgroup
|
||||||
au!
|
au!
|
||||||
autocmd BufReadCmd t call ReadFunc()
|
autocmd BufReadCmd test_changed.txt call ReadFunc()
|
||||||
augroup END
|
augroup END
|
||||||
|
|
||||||
bwipe!
|
new | only
|
||||||
let words = [ "a", "b" ]
|
let words = [ "a", "b" ]
|
||||||
let qflist = []
|
let qflist = []
|
||||||
for word in words
|
for word in words
|
||||||
call add(qflist, {'filename': 't'})
|
call add(qflist, {'filename': 'test_changed.txt'})
|
||||||
exec "call " . Xsetlist . "qflist, '')"
|
call Xsetlist(qflist, ' ')
|
||||||
endfor
|
endfor
|
||||||
exec "call assert_fails('" . Xrewind . "', '" . ErrorNr . ":')"
|
exec "call assert_fails('" . Xrewind . "', '" . ErrorNr . ":')"
|
||||||
|
|
||||||
@@ -745,3 +745,89 @@ function Test_setqflist()
|
|||||||
|
|
||||||
call delete('Xtestfile')
|
call delete('Xtestfile')
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! XquickfixSetListWithAct(cchar)
|
||||||
|
let Xolder = a:cchar . 'older'
|
||||||
|
let Xnewer = a:cchar . 'newer'
|
||||||
|
if a:cchar == 'c'
|
||||||
|
let Xsetlist = function('setqflist')
|
||||||
|
let Xgetlist = function('getqflist')
|
||||||
|
else
|
||||||
|
let Xsetlist = function('setloclist', [0])
|
||||||
|
let Xgetlist = function('getloclist', [0])
|
||||||
|
endif
|
||||||
|
let list1 = [{'filename': 'fnameA', 'text': 'A'},
|
||||||
|
\ {'filename': 'fnameB', 'text': 'B'}]
|
||||||
|
let list2 = [{'filename': 'fnameC', 'text': 'C'},
|
||||||
|
\ {'filename': 'fnameD', 'text': 'D'},
|
||||||
|
\ {'filename': 'fnameE', 'text': 'E'}]
|
||||||
|
|
||||||
|
" {action} is unspecified. Same as specifing ' '.
|
||||||
|
new | only
|
||||||
|
exec "silent! " . Xnewer . "99"
|
||||||
|
call Xsetlist(list1)
|
||||||
|
call Xsetlist(list2)
|
||||||
|
let li = Xgetlist()
|
||||||
|
call assert_equal(3, len(li))
|
||||||
|
call assert_equal('C', li[0]['text'])
|
||||||
|
call assert_equal('D', li[1]['text'])
|
||||||
|
call assert_equal('E', li[2]['text'])
|
||||||
|
exec "silent! " . Xolder
|
||||||
|
let li = Xgetlist()
|
||||||
|
call assert_equal(2, len(li))
|
||||||
|
call assert_equal('A', li[0]['text'])
|
||||||
|
call assert_equal('B', li[1]['text'])
|
||||||
|
|
||||||
|
" {action} is specified ' '.
|
||||||
|
new | only
|
||||||
|
exec "silent! " . Xnewer . "99"
|
||||||
|
call Xsetlist(list1)
|
||||||
|
call Xsetlist(list2, ' ')
|
||||||
|
let li = Xgetlist()
|
||||||
|
call assert_equal(3, len(li))
|
||||||
|
call assert_equal('C', li[0]['text'])
|
||||||
|
call assert_equal('D', li[1]['text'])
|
||||||
|
call assert_equal('E', li[2]['text'])
|
||||||
|
exec "silent! " . Xolder
|
||||||
|
let li = Xgetlist()
|
||||||
|
call assert_equal(2, len(li))
|
||||||
|
call assert_equal('A', li[0]['text'])
|
||||||
|
call assert_equal('B', li[1]['text'])
|
||||||
|
|
||||||
|
" {action} is specified 'a'.
|
||||||
|
new | only
|
||||||
|
exec "silent! " . Xnewer . "99"
|
||||||
|
call Xsetlist(list1)
|
||||||
|
call Xsetlist(list2, 'a')
|
||||||
|
let li = Xgetlist()
|
||||||
|
call assert_equal(5, len(li))
|
||||||
|
call assert_equal('A', li[0]['text'])
|
||||||
|
call assert_equal('B', li[1]['text'])
|
||||||
|
call assert_equal('C', li[2]['text'])
|
||||||
|
call assert_equal('D', li[3]['text'])
|
||||||
|
call assert_equal('E', li[4]['text'])
|
||||||
|
|
||||||
|
" {action} is specified 'r'.
|
||||||
|
new | only
|
||||||
|
exec "silent! " . Xnewer . "99"
|
||||||
|
call Xsetlist(list1)
|
||||||
|
call Xsetlist(list2, 'r')
|
||||||
|
let li = Xgetlist()
|
||||||
|
call assert_equal(3, len(li))
|
||||||
|
call assert_equal('C', li[0]['text'])
|
||||||
|
call assert_equal('D', li[1]['text'])
|
||||||
|
call assert_equal('E', li[2]['text'])
|
||||||
|
|
||||||
|
" Test for wrong value.
|
||||||
|
new | only
|
||||||
|
call assert_fails("call Xsetlist(0)", 'E714:')
|
||||||
|
call assert_fails("call Xsetlist(list1, '')", 'E927:')
|
||||||
|
call assert_fails("call Xsetlist(list1, 'aa')", 'E927:')
|
||||||
|
call assert_fails("call Xsetlist(list1, ' a')", 'E927:')
|
||||||
|
call assert_fails("call Xsetlist(list1, 0)", 'E928:')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
function Test_quickfix_set_list_with_act()
|
||||||
|
call XquickfixSetListWithAct('c')
|
||||||
|
call XquickfixSetListWithAct('l')
|
||||||
|
endfunction
|
||||||
|
@@ -748,6 +748,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1768,
|
||||||
/**/
|
/**/
|
||||||
1767,
|
1767,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user