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)
Files:      src/eval.c, src/testdir/test_quickfix.vim


*** ../vim-7.4.1767/src/eval.c  2016-04-21 08:56:07.022097293 +0200
--- src/eval.c  2016-04-21 19:28:49.935082045 +0200
***************
*** 98,103 ****
--- 98,104 ----
  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_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_dictkey = N_("E716: Key not present in Dictionary: %s");
  static char *e_funcexts = N_("E122: Function %s already exists, add ! to 
replace it");
***************
*** 18280,18287 ****
      typval_T  *rettv)
  {
  #ifdef FEAT_QUICKFIX
      char_u    *act;
!     int               action = ' ';
  #endif
  
      rettv->vval.v_number = -1;
--- 18281,18289 ----
      typval_T  *rettv)
  {
  #ifdef FEAT_QUICKFIX
+     static char *e_invact = N_("E927: Invalid action: '%s'");
      char_u    *act;
!     int               action = 0;
  #endif
  
      rettv->vval.v_number = -1;
***************
*** 18298,18308 ****
            act = get_tv_string_chk(action_arg);
            if (act == NULL)
                return;         /* type error; errmsg already given */
!           if (*act == 'a' || *act == 'r')
                action = *act;
        }
  
!       if (l != NULL && set_errorlist(wp, l, action,
               (char_u *)(wp == NULL ? "setqflist()" : "setloclist()")) == OK)
            rettv->vval.v_number = 0;
      }
--- 18300,18316 ----
            act = get_tv_string_chk(action_arg);
            if (act == NULL)
                return;         /* type error; errmsg already given */
!           if ((*act == 'a' || *act == 'r' || *act == ' ') && act[1] == NUL)
                action = *act;
+           else
+               EMSG2(_(e_invact), act);
        }
+       else if (action_arg->v_type == VAR_UNKNOWN)
+           action = ' ';
+       else
+           EMSG(_(e_stringreq));
  
!       if (l != NULL && action && set_errorlist(wp, l, action,
               (char_u *)(wp == NULL ? "setqflist()" : "setloclist()")) == OK)
            rettv->vval.v_number = 0;
      }
*** ../vim-7.4.1767/src/testdir/test_quickfix.vim       2016-04-18 
20:03:54.103519308 +0200
--- src/testdir/test_quickfix.vim       2016-04-21 19:33:04.100406223 +0200
***************
*** 501,507 ****
  function Test_locationlist_curwin_was_closed()
      augroup testgroup
        au!
!       autocmd BufReadCmd t call R(expand("<amatch>"))
      augroup END
  
      function! R(n)
--- 501,507 ----
  function Test_locationlist_curwin_was_closed()
      augroup testgroup
        au!
!       autocmd BufReadCmd test_curwin.txt call R(expand("<amatch>"))
      augroup END
  
      function! R(n)
***************
*** 510,516 ****
  
      new
      let q = []
!     call add(q, {'filename': 't' })
      call setloclist(0, q)
      call assert_fails('lrewind', 'E924:')
  
--- 510,516 ----
  
      new
      let q = []
!     call add(q, {'filename': 'test_curwin.txt' })
      call setloclist(0, q)
      call assert_fails('lrewind', 'E924:')
  
***************
*** 643,656 ****
    let Xgetexpr = a:cchar . 'getexpr'
    let Xrewind = a:cchar . 'rewind'
    if a:cchar == 'c'
!     let Xsetlist = 'setqflist('
      let ErrorNr = 'E925'
      function! ReadFunc()
        colder
        cgetexpr []
      endfunc
    else
!     let Xsetlist = 'setloclist(0,'
      let ErrorNr = 'E926'
      function! ReadFunc()
        lolder
--- 643,656 ----
    let Xgetexpr = a:cchar . 'getexpr'
    let Xrewind = a:cchar . 'rewind'
    if a:cchar == 'c'
!     let Xsetlist = function('setqflist')
      let ErrorNr = 'E925'
      function! ReadFunc()
        colder
        cgetexpr []
      endfunc
    else
!     let Xsetlist = function('setloclist', [0])
      let ErrorNr = 'E926'
      function! ReadFunc()
        lolder
***************
*** 660,674 ****
  
    augroup testgroup
      au!
!     autocmd BufReadCmd t call ReadFunc()
    augroup END
  
!   bwipe!
    let words = [ "a", "b" ]
    let qflist = []
    for word in words
!     call add(qflist, {'filename': 't'})
!     exec "call " . Xsetlist . "qflist, '')"
    endfor
    exec "call assert_fails('" . Xrewind . "', '" . ErrorNr . ":')"
  
--- 660,674 ----
  
    augroup testgroup
      au!
!     autocmd BufReadCmd test_changed.txt call ReadFunc()
    augroup END
  
!   new | only
    let words = [ "a", "b" ]
    let qflist = []
    for word in words
!     call add(qflist, {'filename': 'test_changed.txt'})
!     call Xsetlist(qflist, ' ')
    endfor
    exec "call assert_fails('" . Xrewind . "', '" . ErrorNr . ":')"
  
***************
*** 745,747 ****
--- 745,833 ----
  
    call delete('Xtestfile')
  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
*** ../vim-7.4.1767/src/version.c       2016-04-21 18:20:03.662235811 +0200
--- src/version.c       2016-04-21 19:32:13.160942225 +0200
***************
*** 750,751 ****
--- 750,753 ----
  {   /* Add new patch number below this line */
+ /**/
+     1768,
  /**/

-- 
WOMAN:   I didn't know we had a king. I thought we were an autonomous
         collective.
DENNIS:  You're fooling yourself.  We're living in a dictatorship.  A
         self-perpetuating autocracy in which the working classes--
WOMAN:   Oh there you go, bringing class into it again.
DENNIS:  That's what it's all about if only people would--
                                  The Quest for the Holy Grail (Monty Python)

 /// Bram Moolenaar -- [email protected] -- 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    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui