0
0
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:
Bram Moolenaar
2016-04-21 19:38:07 +02:00
parent 4adfaabfe7
commit d106e5ba7f
3 changed files with 107 additions and 11 deletions

View File

@@ -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;
} }

View File

@@ -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

View File

@@ -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,
/**/ /**/