Karsten Hopp 8eff73
To: vim_dev@googlegroups.com
Karsten Hopp 8eff73
Subject: Patch 7.3.715
Karsten Hopp 8eff73
Fcc: outbox
Karsten Hopp 8eff73
From: Bram Moolenaar <Bram@moolenaar.net>
Karsten Hopp 8eff73
Mime-Version: 1.0
Karsten Hopp 8eff73
Content-Type: text/plain; charset=UTF-8
Karsten Hopp 8eff73
Content-Transfer-Encoding: 8bit
Karsten Hopp 8eff73
------------
Karsten Hopp 8eff73
Karsten Hopp 8eff73
Patch 7.3.715
Karsten Hopp 8eff73
Problem:    Crash when calling setloclist() in BufUnload autocmd. (Marcin
Karsten Hopp 8eff73
	    Szamotulski)
Karsten Hopp 8eff73
Solution:   Set w_llist to NULL when it was freed.  Also add a test.
Karsten Hopp 8eff73
	    (Christian Brabandt)
Karsten Hopp 8eff73
Files:	    src/quickfix.c, src/testdir/test49.ok, src/testdir/test49.vim
Karsten Hopp 8eff73
Karsten Hopp 8eff73
Karsten Hopp 8eff73
*** ../vim-7.3.714/src/quickfix.c	2012-06-29 12:57:03.000000000 +0200
Karsten Hopp 8eff73
--- src/quickfix.c	2012-11-14 22:33:20.000000000 +0100
Karsten Hopp 8eff73
***************
Karsten Hopp 8eff73
*** 107,113 ****
Karsten Hopp 8eff73
  };
Karsten Hopp 8eff73
  
Karsten Hopp 8eff73
  static int	qf_init_ext __ARGS((qf_info_T *qi, char_u *efile, buf_T *buf, typval_T *tv, char_u *errorformat, int newlist, linenr_T lnumfirst, linenr_T lnumlast, char_u *qf_title));
Karsten Hopp 8eff73
! static void	qf_new_list __ARGS((qf_info_T *qi, char_u *qf_title));
Karsten Hopp 8eff73
  static void	ll_free_all __ARGS((qf_info_T **pqi));
Karsten Hopp 8eff73
  static int	qf_add_entry __ARGS((qf_info_T *qi, qfline_T **prevp, char_u *dir, char_u *fname, int bufnum, char_u *mesg, long lnum, int col, int vis_col, char_u *pattern, int nr, int type, int valid));
Karsten Hopp 8eff73
  static qf_info_T *ll_new_list __ARGS((void));
Karsten Hopp 8eff73
--- 107,113 ----
Karsten Hopp 8eff73
  };
Karsten Hopp 8eff73
  
Karsten Hopp 8eff73
  static int	qf_init_ext __ARGS((qf_info_T *qi, char_u *efile, buf_T *buf, typval_T *tv, char_u *errorformat, int newlist, linenr_T lnumfirst, linenr_T lnumlast, char_u *qf_title));
Karsten Hopp 8eff73
! static void	qf_new_list __ARGS((qf_info_T *qi, char_u *qf_title, win_T *wp));
Karsten Hopp 8eff73
  static void	ll_free_all __ARGS((qf_info_T **pqi));
Karsten Hopp 8eff73
  static int	qf_add_entry __ARGS((qf_info_T *qi, qfline_T **prevp, char_u *dir, char_u *fname, int bufnum, char_u *mesg, long lnum, int col, int vis_col, char_u *pattern, int nr, int type, int valid));
Karsten Hopp 8eff73
  static qf_info_T *ll_new_list __ARGS((void));
Karsten Hopp 8eff73
***************
Karsten Hopp 8eff73
*** 266,272 ****
Karsten Hopp 8eff73
  
Karsten Hopp 8eff73
      if (newlist || qi->qf_curlist == qi->qf_listcount)
Karsten Hopp 8eff73
  	/* make place for a new list */
Karsten Hopp 8eff73
! 	qf_new_list(qi, qf_title);
Karsten Hopp 8eff73
      else if (qi->qf_lists[qi->qf_curlist].qf_count > 0)
Karsten Hopp 8eff73
  	/* Adding to existing list, find last entry. */
Karsten Hopp 8eff73
  	for (qfprev = qi->qf_lists[qi->qf_curlist].qf_start;
Karsten Hopp 8eff73
--- 266,272 ----
Karsten Hopp 8eff73
  
Karsten Hopp 8eff73
      if (newlist || qi->qf_curlist == qi->qf_listcount)
Karsten Hopp 8eff73
  	/* make place for a new list */
Karsten Hopp 8eff73
! 	qf_new_list(qi, qf_title, curwin);
Karsten Hopp 8eff73
      else if (qi->qf_lists[qi->qf_curlist].qf_count > 0)
Karsten Hopp 8eff73
  	/* Adding to existing list, find last entry. */
Karsten Hopp 8eff73
  	for (qfprev = qi->qf_lists[qi->qf_curlist].qf_start;
Karsten Hopp 8eff73
***************
Karsten Hopp 8eff73
*** 885,893 ****
Karsten Hopp 8eff73
   * Prepare for adding a new quickfix list.
Karsten Hopp 8eff73
   */
Karsten Hopp 8eff73
      static void
Karsten Hopp 8eff73
! qf_new_list(qi, qf_title)
Karsten Hopp 8eff73
      qf_info_T	*qi;
Karsten Hopp 8eff73
      char_u	*qf_title;
Karsten Hopp 8eff73
  {
Karsten Hopp 8eff73
      int		i;
Karsten Hopp 8eff73
  
Karsten Hopp 8eff73
--- 885,894 ----
Karsten Hopp 8eff73
   * Prepare for adding a new quickfix list.
Karsten Hopp 8eff73
   */
Karsten Hopp 8eff73
      static void
Karsten Hopp 8eff73
! qf_new_list(qi, qf_title, wp)
Karsten Hopp 8eff73
      qf_info_T	*qi;
Karsten Hopp 8eff73
      char_u	*qf_title;
Karsten Hopp 8eff73
+     win_T	*wp;
Karsten Hopp 8eff73
  {
Karsten Hopp 8eff73
      int		i;
Karsten Hopp 8eff73
  
Karsten Hopp 8eff73
***************
Karsten Hopp 8eff73
*** 897,903 ****
Karsten Hopp 8eff73
--- 898,908 ----
Karsten Hopp 8eff73
       * way with ":grep'.
Karsten Hopp 8eff73
       */
Karsten Hopp 8eff73
      while (qi->qf_listcount > qi->qf_curlist + 1)
Karsten Hopp 8eff73
+     {
Karsten Hopp 8eff73
+ 	if (wp != NULL && wp->w_llist == qi)
Karsten Hopp 8eff73
+ 	    wp->w_llist = NULL;
Karsten Hopp 8eff73
  	qf_free(qi, --qi->qf_listcount);
Karsten Hopp 8eff73
+     }
Karsten Hopp 8eff73
  
Karsten Hopp 8eff73
      /*
Karsten Hopp 8eff73
       * When the stack is full, remove to oldest entry
Karsten Hopp 8eff73
***************
Karsten Hopp 8eff73
*** 905,910 ****
Karsten Hopp 8eff73
--- 910,917 ----
Karsten Hopp 8eff73
       */
Karsten Hopp 8eff73
      if (qi->qf_listcount == LISTCOUNT)
Karsten Hopp 8eff73
      {
Karsten Hopp 8eff73
+ 	if (wp != NULL && wp->w_llist == qi)
Karsten Hopp 8eff73
+ 	    wp->w_llist = NULL;
Karsten Hopp 8eff73
  	qf_free(qi, 0);
Karsten Hopp 8eff73
  	for (i = 1; i < LISTCOUNT; ++i)
Karsten Hopp 8eff73
  	    qi->qf_lists[i - 1] = qi->qf_lists[i];
Karsten Hopp 8eff73
***************
Karsten Hopp 8eff73
*** 3181,3187 ****
Karsten Hopp 8eff73
  	 eap->cmdidx != CMD_vimgrepadd && eap->cmdidx != CMD_lvimgrepadd)
Karsten Hopp 8eff73
  					|| qi->qf_curlist == qi->qf_listcount)
Karsten Hopp 8eff73
  	/* make place for a new list */
Karsten Hopp 8eff73
! 	qf_new_list(qi, *eap->cmdlinep);
Karsten Hopp 8eff73
      else if (qi->qf_lists[qi->qf_curlist].qf_count > 0)
Karsten Hopp 8eff73
  	/* Adding to existing list, find last entry. */
Karsten Hopp 8eff73
  	for (prevp = qi->qf_lists[qi->qf_curlist].qf_start;
Karsten Hopp 8eff73
--- 3188,3194 ----
Karsten Hopp 8eff73
  	 eap->cmdidx != CMD_vimgrepadd && eap->cmdidx != CMD_lvimgrepadd)
Karsten Hopp 8eff73
  					|| qi->qf_curlist == qi->qf_listcount)
Karsten Hopp 8eff73
  	/* make place for a new list */
Karsten Hopp 8eff73
! 	qf_new_list(qi, *eap->cmdlinep, curwin);
Karsten Hopp 8eff73
      else if (qi->qf_lists[qi->qf_curlist].qf_count > 0)
Karsten Hopp 8eff73
  	/* Adding to existing list, find last entry. */
Karsten Hopp 8eff73
  	for (prevp = qi->qf_lists[qi->qf_curlist].qf_start;
Karsten Hopp 8eff73
***************
Karsten Hopp 8eff73
*** 3747,3753 ****
Karsten Hopp 8eff73
  
Karsten Hopp 8eff73
      if (action == ' ' || qi->qf_curlist == qi->qf_listcount)
Karsten Hopp 8eff73
  	/* make place for a new list */
Karsten Hopp 8eff73
! 	qf_new_list(qi, title);
Karsten Hopp 8eff73
      else if (action == 'a' && qi->qf_lists[qi->qf_curlist].qf_count > 0)
Karsten Hopp 8eff73
  	/* Adding to existing list, find last entry. */
Karsten Hopp 8eff73
  	for (prevp = qi->qf_lists[qi->qf_curlist].qf_start;
Karsten Hopp 8eff73
--- 3754,3760 ----
Karsten Hopp 8eff73
  
Karsten Hopp 8eff73
      if (action == ' ' || qi->qf_curlist == qi->qf_listcount)
Karsten Hopp 8eff73
  	/* make place for a new list */
Karsten Hopp 8eff73
! 	qf_new_list(qi, title, wp);
Karsten Hopp 8eff73
      else if (action == 'a' && qi->qf_lists[qi->qf_curlist].qf_count > 0)
Karsten Hopp 8eff73
  	/* Adding to existing list, find last entry. */
Karsten Hopp 8eff73
  	for (prevp = qi->qf_lists[qi->qf_curlist].qf_start;
Karsten Hopp 8eff73
***************
Karsten Hopp 8eff73
*** 4029,4035 ****
Karsten Hopp 8eff73
  #endif
Karsten Hopp 8eff73
  
Karsten Hopp 8eff73
  	/* create a new quickfix list */
Karsten Hopp 8eff73
! 	qf_new_list(qi, *eap->cmdlinep);
Karsten Hopp 8eff73
  
Karsten Hopp 8eff73
  	/* Go through all directories in 'runtimepath' */
Karsten Hopp 8eff73
  	p = p_rtp;
Karsten Hopp 8eff73
--- 4036,4042 ----
Karsten Hopp 8eff73
  #endif
Karsten Hopp 8eff73
  
Karsten Hopp 8eff73
  	/* create a new quickfix list */
Karsten Hopp 8eff73
! 	qf_new_list(qi, *eap->cmdlinep, wp);
Karsten Hopp 8eff73
  
Karsten Hopp 8eff73
  	/* Go through all directories in 'runtimepath' */
Karsten Hopp 8eff73
  	p = p_rtp;
Karsten Hopp 8eff73
*** ../vim-7.3.714/src/testdir/test49.ok	2010-08-15 21:57:29.000000000 +0200
Karsten Hopp 8eff73
--- src/testdir/test49.ok	2012-11-14 22:26:13.000000000 +0100
Karsten Hopp 8eff73
***************
Karsten Hopp 8eff73
*** 85,92 ****
Karsten Hopp 8eff73
  *** Test  83: OK (2835)
Karsten Hopp 8eff73
  *** Test  84: OK (934782101)
Karsten Hopp 8eff73
  *** Test  85: OK (198689)
Karsten Hopp 8eff73
! --- Test  86: All tests were run with throwing exceptions on error.
Karsten Hopp 8eff73
  	      The $VIMNOERRTHROW control is not configured.
Karsten Hopp 8eff73
! --- Test  86: All tests were run with throwing exceptions on interrupt.
Karsten Hopp 8eff73
  	      The $VIMNOINTTHROW control is not configured.
Karsten Hopp 8eff73
! *** Test  86: OK (50443995)
Karsten Hopp 8eff73
--- 85,94 ----
Karsten Hopp 8eff73
  *** Test  83: OK (2835)
Karsten Hopp 8eff73
  *** Test  84: OK (934782101)
Karsten Hopp 8eff73
  *** Test  85: OK (198689)
Karsten Hopp 8eff73
! --- Test  86: No Crash for vimgrep on BufUnload
Karsten Hopp 8eff73
! *** Test  86: OK (0)
Karsten Hopp 8eff73
! --- Test  87: All tests were run with throwing exceptions on error.
Karsten Hopp 8eff73
  	      The $VIMNOERRTHROW control is not configured.
Karsten Hopp 8eff73
! --- Test  87: All tests were run with throwing exceptions on interrupt.
Karsten Hopp 8eff73
  	      The $VIMNOINTTHROW control is not configured.
Karsten Hopp 8eff73
! *** Test  87: OK (50443995)
Karsten Hopp 8eff73
*** ../vim-7.3.714/src/testdir/test49.vim	2010-09-29 16:55:45.000000000 +0200
Karsten Hopp 8eff73
--- src/testdir/test49.vim	2012-11-14 22:26:13.000000000 +0100
Karsten Hopp 8eff73
***************
Karsten Hopp 8eff73
*** 9603,9611 ****
Karsten Hopp 8eff73
  
Karsten Hopp 8eff73
  Xcheck 198689
Karsten Hopp 8eff73
  
Karsten Hopp 8eff73
  
Karsten Hopp 8eff73
  "-------------------------------------------------------------------------------
Karsten Hopp 8eff73
! " Test 86:  $VIMNOERRTHROW and $VIMNOINTTHROW support			    {{{1
Karsten Hopp 8eff73
  "
Karsten Hopp 8eff73
  "	    It is possible to configure Vim for throwing exceptions on error
Karsten Hopp 8eff73
  "	    or interrupt, controlled by variables $VIMNOERRTHROW and
Karsten Hopp 8eff73
--- 9603,9630 ----
Karsten Hopp 8eff73
  
Karsten Hopp 8eff73
  Xcheck 198689
Karsten Hopp 8eff73
  
Karsten Hopp 8eff73
+ "-------------------------------------------------------------------------------
Karsten Hopp 8eff73
+ " Test 86   setloclist crash						    {{{1
Karsten Hopp 8eff73
+ "
Karsten Hopp 8eff73
+ "	    Executing a setloclist() on BufUnload shouldn't crash Vim
Karsten Hopp 8eff73
+ "-------------------------------------------------------------------------------
Karsten Hopp 8eff73
+ 
Karsten Hopp 8eff73
+ func F
Karsten Hopp 8eff73
+     au BufUnload * :call setloclist(0, [{'bufnr':1, 'lnum':1, 'col':1, 'text': 'tango down'}])
Karsten Hopp 8eff73
+ 
Karsten Hopp 8eff73
+     :lvimgrep /.*/ *
Karsten Hopp 8eff73
+ endfunc
Karsten Hopp 8eff73
+ 
Karsten Hopp 8eff73
+ XpathINIT
Karsten Hopp 8eff73
+ 
Karsten Hopp 8eff73
+ ExecAsScript F
Karsten Hopp 8eff73
+ 
Karsten Hopp 8eff73
+ delfunction F
Karsten Hopp 8eff73
+ Xout  "No Crash for vimgrep on BufUnload"
Karsten Hopp 8eff73
+ Xcheck 0 
Karsten Hopp 8eff73
  
Karsten Hopp 8eff73
  "-------------------------------------------------------------------------------
Karsten Hopp 8eff73
! " Test 87:  $VIMNOERRTHROW and $VIMNOINTTHROW support			    {{{1
Karsten Hopp 8eff73
  "
Karsten Hopp 8eff73
  "	    It is possible to configure Vim for throwing exceptions on error
Karsten Hopp 8eff73
  "	    or interrupt, controlled by variables $VIMNOERRTHROW and
Karsten Hopp 8eff73
*** ../vim-7.3.714/src/version.c	2012-11-14 20:52:22.000000000 +0100
Karsten Hopp 8eff73
--- src/version.c	2012-11-14 22:36:45.000000000 +0100
Karsten Hopp 8eff73
***************
Karsten Hopp 8eff73
*** 727,728 ****
Karsten Hopp 8eff73
--- 727,730 ----
Karsten Hopp 8eff73
  {   /* Add new patch number below this line */
Karsten Hopp 8eff73
+ /**/
Karsten Hopp 8eff73
+     715,
Karsten Hopp 8eff73
  /**/
Karsten Hopp 8eff73
Karsten Hopp 8eff73
-- 
Karsten Hopp 8eff73
One difference between a man and a machine is that a machine is quiet
Karsten Hopp 8eff73
when well oiled.
Karsten Hopp 8eff73
Karsten Hopp 8eff73
 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
Karsten Hopp 8eff73
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
Karsten Hopp 8eff73
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
Karsten Hopp 8eff73
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///