To: vim_dev@googlegroups.com
Subject: Patch 7.3.715
Fcc: outbox
From: Bram Moolenaar <Bram@moolenaar.net>
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
------------

Patch 7.3.715
Problem:    Crash when calling setloclist() in BufUnload autocmd. (Marcin
	    Szamotulski)
Solution:   Set w_llist to NULL when it was freed.  Also add a test.
	    (Christian Brabandt)
Files:	    src/quickfix.c, src/testdir/test49.ok, src/testdir/test49.vim


*** ../vim-7.3.714/src/quickfix.c	2012-06-29 12:57:03.000000000 +0200
--- src/quickfix.c	2012-11-14 22:33:20.000000000 +0100
***************
*** 107,113 ****
  };
  
  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));
! static void	qf_new_list __ARGS((qf_info_T *qi, char_u *qf_title));
  static void	ll_free_all __ARGS((qf_info_T **pqi));
  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));
  static qf_info_T *ll_new_list __ARGS((void));
--- 107,113 ----
  };
  
  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));
! static void	qf_new_list __ARGS((qf_info_T *qi, char_u *qf_title, win_T *wp));
  static void	ll_free_all __ARGS((qf_info_T **pqi));
  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));
  static qf_info_T *ll_new_list __ARGS((void));
***************
*** 266,272 ****
  
      if (newlist || qi->qf_curlist == qi->qf_listcount)
  	/* make place for a new list */
! 	qf_new_list(qi, qf_title);
      else if (qi->qf_lists[qi->qf_curlist].qf_count > 0)
  	/* Adding to existing list, find last entry. */
  	for (qfprev = qi->qf_lists[qi->qf_curlist].qf_start;
--- 266,272 ----
  
      if (newlist || qi->qf_curlist == qi->qf_listcount)
  	/* make place for a new list */
! 	qf_new_list(qi, qf_title, curwin);
      else if (qi->qf_lists[qi->qf_curlist].qf_count > 0)
  	/* Adding to existing list, find last entry. */
  	for (qfprev = qi->qf_lists[qi->qf_curlist].qf_start;
***************
*** 885,893 ****
   * Prepare for adding a new quickfix list.
   */
      static void
! qf_new_list(qi, qf_title)
      qf_info_T	*qi;
      char_u	*qf_title;
  {
      int		i;
  
--- 885,894 ----
   * Prepare for adding a new quickfix list.
   */
      static void
! qf_new_list(qi, qf_title, wp)
      qf_info_T	*qi;
      char_u	*qf_title;
+     win_T	*wp;
  {
      int		i;
  
***************
*** 897,903 ****
--- 898,908 ----
       * way with ":grep'.
       */
      while (qi->qf_listcount > qi->qf_curlist + 1)
+     {
+ 	if (wp != NULL && wp->w_llist == qi)
+ 	    wp->w_llist = NULL;
  	qf_free(qi, --qi->qf_listcount);
+     }
  
      /*
       * When the stack is full, remove to oldest entry
***************
*** 905,910 ****
--- 910,917 ----
       */
      if (qi->qf_listcount == LISTCOUNT)
      {
+ 	if (wp != NULL && wp->w_llist == qi)
+ 	    wp->w_llist = NULL;
  	qf_free(qi, 0);
  	for (i = 1; i < LISTCOUNT; ++i)
  	    qi->qf_lists[i - 1] = qi->qf_lists[i];
***************
*** 3181,3187 ****
  	 eap->cmdidx != CMD_vimgrepadd && eap->cmdidx != CMD_lvimgrepadd)
  					|| qi->qf_curlist == qi->qf_listcount)
  	/* make place for a new list */
! 	qf_new_list(qi, *eap->cmdlinep);
      else if (qi->qf_lists[qi->qf_curlist].qf_count > 0)
  	/* Adding to existing list, find last entry. */
  	for (prevp = qi->qf_lists[qi->qf_curlist].qf_start;
--- 3188,3194 ----
  	 eap->cmdidx != CMD_vimgrepadd && eap->cmdidx != CMD_lvimgrepadd)
  					|| qi->qf_curlist == qi->qf_listcount)
  	/* make place for a new list */
! 	qf_new_list(qi, *eap->cmdlinep, curwin);
      else if (qi->qf_lists[qi->qf_curlist].qf_count > 0)
  	/* Adding to existing list, find last entry. */
  	for (prevp = qi->qf_lists[qi->qf_curlist].qf_start;
***************
*** 3747,3753 ****
  
      if (action == ' ' || qi->qf_curlist == qi->qf_listcount)
  	/* make place for a new list */
! 	qf_new_list(qi, title);
      else if (action == 'a' && qi->qf_lists[qi->qf_curlist].qf_count > 0)
  	/* Adding to existing list, find last entry. */
  	for (prevp = qi->qf_lists[qi->qf_curlist].qf_start;
--- 3754,3760 ----
  
      if (action == ' ' || qi->qf_curlist == qi->qf_listcount)
  	/* make place for a new list */
! 	qf_new_list(qi, title, wp);
      else if (action == 'a' && qi->qf_lists[qi->qf_curlist].qf_count > 0)
  	/* Adding to existing list, find last entry. */
  	for (prevp = qi->qf_lists[qi->qf_curlist].qf_start;
***************
*** 4029,4035 ****
  #endif
  
  	/* create a new quickfix list */
! 	qf_new_list(qi, *eap->cmdlinep);
  
  	/* Go through all directories in 'runtimepath' */
  	p = p_rtp;
--- 4036,4042 ----
  #endif
  
  	/* create a new quickfix list */
! 	qf_new_list(qi, *eap->cmdlinep, wp);
  
  	/* Go through all directories in 'runtimepath' */
  	p = p_rtp;
*** ../vim-7.3.714/src/testdir/test49.ok	2010-08-15 21:57:29.000000000 +0200
--- src/testdir/test49.ok	2012-11-14 22:26:13.000000000 +0100
***************
*** 85,92 ****
  *** Test  83: OK (2835)
  *** Test  84: OK (934782101)
  *** Test  85: OK (198689)
! --- Test  86: All tests were run with throwing exceptions on error.
  	      The $VIMNOERRTHROW control is not configured.
! --- Test  86: All tests were run with throwing exceptions on interrupt.
  	      The $VIMNOINTTHROW control is not configured.
! *** Test  86: OK (50443995)
--- 85,94 ----
  *** Test  83: OK (2835)
  *** Test  84: OK (934782101)
  *** Test  85: OK (198689)
! --- Test  86: No Crash for vimgrep on BufUnload
! *** Test  86: OK (0)
! --- Test  87: All tests were run with throwing exceptions on error.
  	      The $VIMNOERRTHROW control is not configured.
! --- Test  87: All tests were run with throwing exceptions on interrupt.
  	      The $VIMNOINTTHROW control is not configured.
! *** Test  87: OK (50443995)
*** ../vim-7.3.714/src/testdir/test49.vim	2010-09-29 16:55:45.000000000 +0200
--- src/testdir/test49.vim	2012-11-14 22:26:13.000000000 +0100
***************
*** 9603,9611 ****
  
  Xcheck 198689
  
  
  "-------------------------------------------------------------------------------
! " Test 86:  $VIMNOERRTHROW and $VIMNOINTTHROW support			    {{{1
  "
  "	    It is possible to configure Vim for throwing exceptions on error
  "	    or interrupt, controlled by variables $VIMNOERRTHROW and
--- 9603,9630 ----
  
  Xcheck 198689
  
+ "-------------------------------------------------------------------------------
+ " Test 86   setloclist crash						    {{{1
+ "
+ "	    Executing a setloclist() on BufUnload shouldn't crash Vim
+ "-------------------------------------------------------------------------------
+ 
+ func F
+     au BufUnload * :call setloclist(0, [{'bufnr':1, 'lnum':1, 'col':1, 'text': 'tango down'}])
+ 
+     :lvimgrep /.*/ *
+ endfunc
+ 
+ XpathINIT
+ 
+ ExecAsScript F
+ 
+ delfunction F
+ Xout  "No Crash for vimgrep on BufUnload"
+ Xcheck 0 
  
  "-------------------------------------------------------------------------------
! " Test 87:  $VIMNOERRTHROW and $VIMNOINTTHROW support			    {{{1
  "
  "	    It is possible to configure Vim for throwing exceptions on error
  "	    or interrupt, controlled by variables $VIMNOERRTHROW and
*** ../vim-7.3.714/src/version.c	2012-11-14 20:52:22.000000000 +0100
--- src/version.c	2012-11-14 22:36:45.000000000 +0100
***************
*** 727,728 ****
--- 727,730 ----
  {   /* Add new patch number below this line */
+ /**/
+     715,
  /**/

-- 
One difference between a man and a machine is that a machine is quiet
when well oiled.

 /// Bram Moolenaar -- Bram@Moolenaar.net -- 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    ///
