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 ///