To: vim-dev@vim.org Subject: Patch 7.2.280 Fcc: outbox From: Bram Moolenaar 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 ///