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