Karsten Hopp a827fd
To: vim-dev@vim.org
Karsten Hopp a827fd
Subject: Patch 7.2.280
Karsten Hopp a827fd
Fcc: outbox
Karsten Hopp a827fd
From: Bram Moolenaar <Bram@moolenaar.net>
Karsten Hopp a827fd
Mime-Version: 1.0
Karsten Hopp a827fd
Content-Type: text/plain; charset=UTF-8
Karsten Hopp a827fd
Content-Transfer-Encoding: 8bit
Karsten Hopp a827fd
------------
Karsten Hopp a827fd
Karsten Hopp a827fd
Patch 7.2.280
Karsten Hopp a827fd
Problem:    A redraw in a custom statusline with %! may cause a crash.
Karsten Hopp a827fd
            (Yukihiro Nakadaira)
Karsten Hopp a827fd
Solution:   Make a copy of 'statusline'.  Also fix typo in function name
Karsten Hopp a827fd
            redraw_custum_statusline. (party by Dominique Pelle)
Karsten Hopp a827fd
Files:      src/screen.c
Karsten Hopp a827fd
Karsten Hopp a827fd
Karsten Hopp a827fd
*** ../vim-7.2.279/src/screen.c	2009-07-29 16:13:35.000000000 +0200
Karsten Hopp a827fd
--- src/screen.c	2009-11-03 17:13:16.000000000 +0100
Karsten Hopp a827fd
***************
Karsten Hopp a827fd
*** 132,138 ****
Karsten Hopp a827fd
  static void draw_vsep_win __ARGS((win_T *wp, int row));
Karsten Hopp a827fd
  #endif
Karsten Hopp a827fd
  #ifdef FEAT_STL_OPT
Karsten Hopp a827fd
! static void redraw_custum_statusline __ARGS((win_T *wp));
Karsten Hopp a827fd
  #endif
Karsten Hopp a827fd
  #ifdef FEAT_SEARCH_EXTRA
Karsten Hopp a827fd
  #define SEARCH_HL_PRIORITY 0
Karsten Hopp a827fd
--- 132,138 ----
Karsten Hopp a827fd
  static void draw_vsep_win __ARGS((win_T *wp, int row));
Karsten Hopp a827fd
  #endif
Karsten Hopp a827fd
  #ifdef FEAT_STL_OPT
Karsten Hopp a827fd
! static void redraw_custom_statusline __ARGS((win_T *wp));
Karsten Hopp a827fd
  #endif
Karsten Hopp a827fd
  #ifdef FEAT_SEARCH_EXTRA
Karsten Hopp a827fd
  #define SEARCH_HL_PRIORITY 0
Karsten Hopp a827fd
***************
Karsten Hopp a827fd
*** 5772,5778 ****
Karsten Hopp a827fd
      else if (*p_stl != NUL || *wp->w_p_stl != NUL)
Karsten Hopp a827fd
      {
Karsten Hopp a827fd
  	/* redraw custom status line */
Karsten Hopp a827fd
! 	redraw_custum_statusline(wp);
Karsten Hopp a827fd
      }
Karsten Hopp a827fd
  #endif
Karsten Hopp a827fd
      else
Karsten Hopp a827fd
--- 5794,5800 ----
Karsten Hopp a827fd
      else if (*p_stl != NUL || *wp->w_p_stl != NUL)
Karsten Hopp a827fd
      {
Karsten Hopp a827fd
  	/* redraw custom status line */
Karsten Hopp a827fd
! 	redraw_custom_statusline(wp);
Karsten Hopp a827fd
      }
Karsten Hopp a827fd
  #endif
Karsten Hopp a827fd
      else
Karsten Hopp a827fd
***************
Karsten Hopp a827fd
*** 5897,5914 ****
Karsten Hopp a827fd
   * errors encountered.
Karsten Hopp a827fd
   */
Karsten Hopp a827fd
      static void
Karsten Hopp a827fd
! redraw_custum_statusline(wp)
Karsten Hopp a827fd
      win_T	    *wp;
Karsten Hopp a827fd
  {
Karsten Hopp a827fd
!     int	save_called_emsg = called_emsg;
Karsten Hopp a827fd
  
Karsten Hopp a827fd
      called_emsg = FALSE;
Karsten Hopp a827fd
      win_redr_custom(wp, FALSE);
Karsten Hopp a827fd
      if (called_emsg)
Karsten Hopp a827fd
  	set_string_option_direct((char_u *)"statusline", -1,
Karsten Hopp a827fd
  		(char_u *)"", OPT_FREE | (*wp->w_p_stl != NUL
Karsten Hopp a827fd
  					? OPT_LOCAL : OPT_GLOBAL), SID_ERROR);
Karsten Hopp a827fd
      called_emsg |= save_called_emsg;
Karsten Hopp a827fd
  }
Karsten Hopp a827fd
  #endif
Karsten Hopp a827fd
  
Karsten Hopp a827fd
--- 5919,5949 ----
Karsten Hopp a827fd
   * errors encountered.
Karsten Hopp a827fd
   */
Karsten Hopp a827fd
      static void
Karsten Hopp a827fd
! redraw_custom_statusline(wp)
Karsten Hopp a827fd
      win_T	    *wp;
Karsten Hopp a827fd
  {
Karsten Hopp a827fd
!     static int	    entered = FALSE;
Karsten Hopp a827fd
!     int		    save_called_emsg = called_emsg;
Karsten Hopp a827fd
! 
Karsten Hopp a827fd
!     /* When called recursively return.  This can happen when the statusline
Karsten Hopp a827fd
!      * contains an expression that triggers a redraw. */
Karsten Hopp a827fd
!     if (entered)
Karsten Hopp a827fd
! 	return;
Karsten Hopp a827fd
!     entered = TRUE;
Karsten Hopp a827fd
  
Karsten Hopp a827fd
      called_emsg = FALSE;
Karsten Hopp a827fd
      win_redr_custom(wp, FALSE);
Karsten Hopp a827fd
      if (called_emsg)
Karsten Hopp a827fd
+     {
Karsten Hopp a827fd
+ 	/* When there is an error disable the statusline, otherwise the
Karsten Hopp a827fd
+ 	 * display is messed up with errors and a redraw triggers the problem
Karsten Hopp a827fd
+ 	 * again and again. */
Karsten Hopp a827fd
  	set_string_option_direct((char_u *)"statusline", -1,
Karsten Hopp a827fd
  		(char_u *)"", OPT_FREE | (*wp->w_p_stl != NUL
Karsten Hopp a827fd
  					? OPT_LOCAL : OPT_GLOBAL), SID_ERROR);
Karsten Hopp a827fd
+     }
Karsten Hopp a827fd
      called_emsg |= save_called_emsg;
Karsten Hopp a827fd
+     entered = FALSE;
Karsten Hopp a827fd
  }
Karsten Hopp a827fd
  #endif
Karsten Hopp a827fd
  
Karsten Hopp a827fd
***************
Karsten Hopp a827fd
*** 6016,6021 ****
Karsten Hopp a827fd
--- 6051,6057 ----
Karsten Hopp a827fd
      int		len;
Karsten Hopp a827fd
      int		fillchar;
Karsten Hopp a827fd
      char_u	buf[MAXPATHL];
Karsten Hopp a827fd
+     char_u	*stl;
Karsten Hopp a827fd
      char_u	*p;
Karsten Hopp a827fd
      struct	stl_hlrec hltab[STL_MAX_ITEM];
Karsten Hopp a827fd
      struct	stl_hlrec tabtab[STL_MAX_ITEM];
Karsten Hopp a827fd
***************
Karsten Hopp a827fd
*** 6025,6031 ****
Karsten Hopp a827fd
      if (wp == NULL)
Karsten Hopp a827fd
      {
Karsten Hopp a827fd
  	/* Use 'tabline'.  Always at the first line of the screen. */
Karsten Hopp a827fd
! 	p = p_tal;
Karsten Hopp a827fd
  	row = 0;
Karsten Hopp a827fd
  	fillchar = ' ';
Karsten Hopp a827fd
  	attr = hl_attr(HLF_TPF);
Karsten Hopp a827fd
--- 6061,6067 ----
Karsten Hopp a827fd
      if (wp == NULL)
Karsten Hopp a827fd
      {
Karsten Hopp a827fd
  	/* Use 'tabline'.  Always at the first line of the screen. */
Karsten Hopp a827fd
! 	stl = p_tal;
Karsten Hopp a827fd
  	row = 0;
Karsten Hopp a827fd
  	fillchar = ' ';
Karsten Hopp a827fd
  	attr = hl_attr(HLF_TPF);
Karsten Hopp a827fd
***************
Karsten Hopp a827fd
*** 6042,6058 ****
Karsten Hopp a827fd
  
Karsten Hopp a827fd
  	if (draw_ruler)
Karsten Hopp a827fd
  	{
Karsten Hopp a827fd
! 	    p = p_ruf;
Karsten Hopp a827fd
  	    /* advance past any leading group spec - implicit in ru_col */
Karsten Hopp a827fd
! 	    if (*p == '%')
Karsten Hopp a827fd
  	    {
Karsten Hopp a827fd
! 		if (*++p == '-')
Karsten Hopp a827fd
! 		    p++;
Karsten Hopp a827fd
! 		if (atoi((char *) p))
Karsten Hopp a827fd
! 		    while (VIM_ISDIGIT(*p))
Karsten Hopp a827fd
! 			p++;
Karsten Hopp a827fd
! 		if (*p++ != '(')
Karsten Hopp a827fd
! 		    p = p_ruf;
Karsten Hopp a827fd
  	    }
Karsten Hopp a827fd
  #ifdef FEAT_VERTSPLIT
Karsten Hopp a827fd
  	    col = ru_col - (Columns - W_WIDTH(wp));
Karsten Hopp a827fd
--- 6078,6094 ----
Karsten Hopp a827fd
  
Karsten Hopp a827fd
  	if (draw_ruler)
Karsten Hopp a827fd
  	{
Karsten Hopp a827fd
! 	    stl = p_ruf;
Karsten Hopp a827fd
  	    /* advance past any leading group spec - implicit in ru_col */
Karsten Hopp a827fd
! 	    if (*stl == '%')
Karsten Hopp a827fd
  	    {
Karsten Hopp a827fd
! 		if (*++stl == '-')
Karsten Hopp a827fd
! 		    stl++;
Karsten Hopp a827fd
! 		if (atoi((char *)stl))
Karsten Hopp a827fd
! 		    while (VIM_ISDIGIT(*stl))
Karsten Hopp a827fd
! 			stl++;
Karsten Hopp a827fd
! 		if (*stl++ != '(')
Karsten Hopp a827fd
! 		    stl = p_ruf;
Karsten Hopp a827fd
  	    }
Karsten Hopp a827fd
  #ifdef FEAT_VERTSPLIT
Karsten Hopp a827fd
  	    col = ru_col - (Columns - W_WIDTH(wp));
Karsten Hopp a827fd
***************
Karsten Hopp a827fd
*** 6081,6089 ****
Karsten Hopp a827fd
  	else
Karsten Hopp a827fd
  	{
Karsten Hopp a827fd
  	    if (*wp->w_p_stl != NUL)
Karsten Hopp a827fd
! 		p = wp->w_p_stl;
Karsten Hopp a827fd
  	    else
Karsten Hopp a827fd
! 		p = p_stl;
Karsten Hopp a827fd
  # ifdef FEAT_EVAL
Karsten Hopp a827fd
  	    use_sandbox = was_set_insecurely((char_u *)"statusline",
Karsten Hopp a827fd
  					 *wp->w_p_stl == NUL ? 0 : OPT_LOCAL);
Karsten Hopp a827fd
--- 6117,6125 ----
Karsten Hopp a827fd
  	else
Karsten Hopp a827fd
  	{
Karsten Hopp a827fd
  	    if (*wp->w_p_stl != NUL)
Karsten Hopp a827fd
! 		stl = wp->w_p_stl;
Karsten Hopp a827fd
  	    else
Karsten Hopp a827fd
! 		stl = p_stl;
Karsten Hopp a827fd
  # ifdef FEAT_EVAL
Karsten Hopp a827fd
  	    use_sandbox = was_set_insecurely((char_u *)"statusline",
Karsten Hopp a827fd
  					 *wp->w_p_stl == NUL ? 0 : OPT_LOCAL);
Karsten Hopp a827fd
***************
Karsten Hopp a827fd
*** 6098,6107 ****
Karsten Hopp a827fd
      if (maxwidth <= 0)
Karsten Hopp a827fd
  	return;
Karsten Hopp a827fd
  
Karsten Hopp a827fd
      width = build_stl_str_hl(wp == NULL ? curwin : wp,
Karsten Hopp a827fd
  				buf, sizeof(buf),
Karsten Hopp a827fd
! 				p, use_sandbox,
Karsten Hopp a827fd
  				fillchar, maxwidth, hltab, tabtab);
Karsten Hopp a827fd
      len = (int)STRLEN(buf);
Karsten Hopp a827fd
  
Karsten Hopp a827fd
      while (width < maxwidth && len < (int)sizeof(buf) - 1)
Karsten Hopp a827fd
--- 6134,6147 ----
Karsten Hopp a827fd
      if (maxwidth <= 0)
Karsten Hopp a827fd
  	return;
Karsten Hopp a827fd
  
Karsten Hopp a827fd
+     /* Make a copy, because the statusline may include a function call that
Karsten Hopp a827fd
+      * might change the option value and free the memory. */
Karsten Hopp a827fd
+     stl = vim_strsave(stl);
Karsten Hopp a827fd
      width = build_stl_str_hl(wp == NULL ? curwin : wp,
Karsten Hopp a827fd
  				buf, sizeof(buf),
Karsten Hopp a827fd
! 				stl, use_sandbox,
Karsten Hopp a827fd
  				fillchar, maxwidth, hltab, tabtab);
Karsten Hopp a827fd
+     vim_free(stl);
Karsten Hopp a827fd
      len = (int)STRLEN(buf);
Karsten Hopp a827fd
  
Karsten Hopp a827fd
      while (width < maxwidth && len < (int)sizeof(buf) - 1)
Karsten Hopp a827fd
***************
Karsten Hopp a827fd
*** 9465,9471 ****
Karsten Hopp a827fd
  #if defined(FEAT_STL_OPT) && defined(FEAT_WINDOWS)
Karsten Hopp a827fd
      if ((*p_stl != NUL || *curwin->w_p_stl != NUL) && curwin->w_status_height)
Karsten Hopp a827fd
      {
Karsten Hopp a827fd
! 	redraw_custum_statusline(curwin);
Karsten Hopp a827fd
      }
Karsten Hopp a827fd
      else
Karsten Hopp a827fd
  #endif
Karsten Hopp a827fd
--- 9505,9511 ----
Karsten Hopp a827fd
  #if defined(FEAT_STL_OPT) && defined(FEAT_WINDOWS)
Karsten Hopp a827fd
      if ((*p_stl != NUL || *curwin->w_p_stl != NUL) && curwin->w_status_height)
Karsten Hopp a827fd
      {
Karsten Hopp a827fd
! 	redraw_custom_statusline(curwin);
Karsten Hopp a827fd
      }
Karsten Hopp a827fd
      else
Karsten Hopp a827fd
  #endif
Karsten Hopp a827fd
*** ../vim-7.2.279/src/version.c	2009-11-03 16:44:04.000000000 +0100
Karsten Hopp a827fd
--- src/version.c	2009-11-03 17:15:35.000000000 +0100
Karsten Hopp a827fd
***************
Karsten Hopp a827fd
*** 678,679 ****
Karsten Hopp a827fd
--- 678,681 ----
Karsten Hopp a827fd
  {   /* Add new patch number below this line */
Karsten Hopp a827fd
+ /**/
Karsten Hopp a827fd
+     280,
Karsten Hopp a827fd
  /**/
Karsten Hopp a827fd
Karsten Hopp a827fd
-- 
Karsten Hopp a827fd
Every exit is an entrance into something else.
Karsten Hopp a827fd
Karsten Hopp a827fd
 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
Karsten Hopp a827fd
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
Karsten Hopp a827fd
\\\        download, build and distribute -- http://www.A-A-P.org        ///
Karsten Hopp a827fd
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///