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 -- b...@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    ///

--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_dev" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---

Raspunde prin e-mail lui