Blob Blame History Raw
To: vim-dev@vim.org
Subject: Patch 7.2.280
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.2.280
Problem:    A redraw in a custom statusline with %! may cause a crash.
            (Yukihiro Nakadaira)
Solution:   Make a copy of 'statusline'.  Also fix typo in function name
            redraw_custum_statusline. (party by Dominique Pelle)
Files:      src/screen.c


*** ../vim-7.2.279/src/screen.c	2009-07-29 16:13:35.000000000 +0200
--- src/screen.c	2009-11-03 17:13:16.000000000 +0100
***************
*** 132,138 ****
  static void draw_vsep_win __ARGS((win_T *wp, int row));
  #endif
  #ifdef FEAT_STL_OPT
! static void redraw_custum_statusline __ARGS((win_T *wp));
  #endif
  #ifdef FEAT_SEARCH_EXTRA
  #define SEARCH_HL_PRIORITY 0
--- 132,138 ----
  static void draw_vsep_win __ARGS((win_T *wp, int row));
  #endif
  #ifdef FEAT_STL_OPT
! static void redraw_custom_statusline __ARGS((win_T *wp));
  #endif
  #ifdef FEAT_SEARCH_EXTRA
  #define SEARCH_HL_PRIORITY 0
***************
*** 5772,5778 ****
      else if (*p_stl != NUL || *wp->w_p_stl != NUL)
      {
  	/* redraw custom status line */
! 	redraw_custum_statusline(wp);
      }
  #endif
      else
--- 5794,5800 ----
      else if (*p_stl != NUL || *wp->w_p_stl != NUL)
      {
  	/* redraw custom status line */
! 	redraw_custom_statusline(wp);
      }
  #endif
      else
***************
*** 5897,5914 ****
   * errors encountered.
   */
      static void
! redraw_custum_statusline(wp)
      win_T	    *wp;
  {
!     int	save_called_emsg = called_emsg;
  
      called_emsg = FALSE;
      win_redr_custom(wp, FALSE);
      if (called_emsg)
  	set_string_option_direct((char_u *)"statusline", -1,
  		(char_u *)"", OPT_FREE | (*wp->w_p_stl != NUL
  					? OPT_LOCAL : OPT_GLOBAL), SID_ERROR);
      called_emsg |= save_called_emsg;
  }
  #endif
  
--- 5919,5949 ----
   * errors encountered.
   */
      static void
! redraw_custom_statusline(wp)
      win_T	    *wp;
  {
!     static int	    entered = FALSE;
!     int		    save_called_emsg = called_emsg;
! 
!     /* When called recursively return.  This can happen when the statusline
!      * contains an expression that triggers a redraw. */
!     if (entered)
! 	return;
!     entered = TRUE;
  
      called_emsg = FALSE;
      win_redr_custom(wp, FALSE);
      if (called_emsg)
+     {
+ 	/* When there is an error disable the statusline, otherwise the
+ 	 * display is messed up with errors and a redraw triggers the problem
+ 	 * again and again. */
  	set_string_option_direct((char_u *)"statusline", -1,
  		(char_u *)"", OPT_FREE | (*wp->w_p_stl != NUL
  					? OPT_LOCAL : OPT_GLOBAL), SID_ERROR);
+     }
      called_emsg |= save_called_emsg;
+     entered = FALSE;
  }
  #endif
  
***************
*** 6016,6021 ****
--- 6051,6057 ----
      int		len;
      int		fillchar;
      char_u	buf[MAXPATHL];
+     char_u	*stl;
      char_u	*p;
      struct	stl_hlrec hltab[STL_MAX_ITEM];
      struct	stl_hlrec tabtab[STL_MAX_ITEM];
***************
*** 6025,6031 ****
      if (wp == NULL)
      {
  	/* Use 'tabline'.  Always at the first line of the screen. */
! 	p = p_tal;
  	row = 0;
  	fillchar = ' ';
  	attr = hl_attr(HLF_TPF);
--- 6061,6067 ----
      if (wp == NULL)
      {
  	/* Use 'tabline'.  Always at the first line of the screen. */
! 	stl = p_tal;
  	row = 0;
  	fillchar = ' ';
  	attr = hl_attr(HLF_TPF);
***************
*** 6042,6058 ****
  
  	if (draw_ruler)
  	{
! 	    p = p_ruf;
  	    /* advance past any leading group spec - implicit in ru_col */
! 	    if (*p == '%')
  	    {
! 		if (*++p == '-')
! 		    p++;
! 		if (atoi((char *) p))
! 		    while (VIM_ISDIGIT(*p))
! 			p++;
! 		if (*p++ != '(')
! 		    p = p_ruf;
  	    }
  #ifdef FEAT_VERTSPLIT
  	    col = ru_col - (Columns - W_WIDTH(wp));
--- 6078,6094 ----
  
  	if (draw_ruler)
  	{
! 	    stl = p_ruf;
  	    /* advance past any leading group spec - implicit in ru_col */
! 	    if (*stl == '%')
  	    {
! 		if (*++stl == '-')
! 		    stl++;
! 		if (atoi((char *)stl))
! 		    while (VIM_ISDIGIT(*stl))
! 			stl++;
! 		if (*stl++ != '(')
! 		    stl = p_ruf;
  	    }
  #ifdef FEAT_VERTSPLIT
  	    col = ru_col - (Columns - W_WIDTH(wp));
***************
*** 6081,6089 ****
  	else
  	{
  	    if (*wp->w_p_stl != NUL)
! 		p = wp->w_p_stl;
  	    else
! 		p = p_stl;
  # ifdef FEAT_EVAL
  	    use_sandbox = was_set_insecurely((char_u *)"statusline",
  					 *wp->w_p_stl == NUL ? 0 : OPT_LOCAL);
--- 6117,6125 ----
  	else
  	{
  	    if (*wp->w_p_stl != NUL)
! 		stl = wp->w_p_stl;
  	    else
! 		stl = p_stl;
  # ifdef FEAT_EVAL
  	    use_sandbox = was_set_insecurely((char_u *)"statusline",
  					 *wp->w_p_stl == NUL ? 0 : OPT_LOCAL);
***************
*** 6098,6107 ****
      if (maxwidth <= 0)
  	return;
  
      width = build_stl_str_hl(wp == NULL ? curwin : wp,
  				buf, sizeof(buf),
! 				p, use_sandbox,
  				fillchar, maxwidth, hltab, tabtab);
      len = (int)STRLEN(buf);
  
      while (width < maxwidth && len < (int)sizeof(buf) - 1)
--- 6134,6147 ----
      if (maxwidth <= 0)
  	return;
  
+     /* Make a copy, because the statusline may include a function call that
+      * might change the option value and free the memory. */
+     stl = vim_strsave(stl);
      width = build_stl_str_hl(wp == NULL ? curwin : wp,
  				buf, sizeof(buf),
! 				stl, use_sandbox,
  				fillchar, maxwidth, hltab, tabtab);
+     vim_free(stl);
      len = (int)STRLEN(buf);
  
      while (width < maxwidth && len < (int)sizeof(buf) - 1)
***************
*** 9465,9471 ****
  #if defined(FEAT_STL_OPT) && defined(FEAT_WINDOWS)
      if ((*p_stl != NUL || *curwin->w_p_stl != NUL) && curwin->w_status_height)
      {
! 	redraw_custum_statusline(curwin);
      }
      else
  #endif
--- 9505,9511 ----
  #if defined(FEAT_STL_OPT) && defined(FEAT_WINDOWS)
      if ((*p_stl != NUL || *curwin->w_p_stl != NUL) && curwin->w_status_height)
      {
! 	redraw_custom_statusline(curwin);
      }
      else
  #endif
*** ../vim-7.2.279/src/version.c	2009-11-03 16:44:04.000000000 +0100
--- src/version.c	2009-11-03 17:15:35.000000000 +0100
***************
*** 678,679 ****
--- 678,681 ----
  {   /* Add new patch number below this line */
+ /**/
+     280,
  /**/

-- 
Every exit is an entrance into something else.

 /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\        download, build and distribute -- http://www.A-A-P.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///