From 7b224fdf4a29f115567d4fc8629c1cef92d8444a Mon Sep 17 00:00:00 2001 From: Luuk van Baal Date: Mon, 7 Nov 2022 12:16:51 +0000 Subject: [PATCH] patch 9.0.0844: handling 'statusline' errors is spread out Problem: Handling 'statusline' errors is spread out. Solution: Pass the option name to the lower levels so the option can be reset there when an error is encountered. (Luuk van Baal, closes #11467) --- src/buffer.c | 60 ++++++++++++++++++++------------------------ src/drawscreen.c | 17 ------------- src/gui.c | 9 +------ src/hardcopy.c | 9 ++----- src/proto/buffer.pro | 4 +-- src/screen.c | 33 +++++++----------------- src/version.c | 2 ++ 7 files changed, 43 insertions(+), 91 deletions(-) diff --git a/src/buffer.c b/src/buffer.c index 0714f62f8..de4c40b58 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -3959,20 +3959,9 @@ maketitle(void) { #ifdef FEAT_STL_OPT if (stl_syntax & STL_IN_TITLE) - { - int use_sandbox = FALSE; - int called_emsg_before = called_emsg; - -# ifdef FEAT_EVAL - use_sandbox = was_set_insecurely((char_u *)"titlestring", 0); -# endif - build_stl_str_hl(curwin, title_str, sizeof(buf), - p_titlestring, use_sandbox, - 0, maxlen, NULL, NULL); - if (called_emsg > called_emsg_before) - set_string_option_direct((char_u *)"titlestring", -1, - (char_u *)"", OPT_FREE, SID_ERROR); - } + build_stl_str_hl(curwin, title_str, sizeof(buf), p_titlestring, + (char_u *)"titlestring", 0, + 0, maxlen, NULL, NULL); else #endif title_str = p_titlestring; @@ -4090,20 +4079,8 @@ maketitle(void) { #ifdef FEAT_STL_OPT if (stl_syntax & STL_IN_ICON) - { - int use_sandbox = FALSE; - int called_emsg_before = called_emsg; - -# ifdef FEAT_EVAL - use_sandbox = was_set_insecurely((char_u *)"iconstring", 0); -# endif - build_stl_str_hl(curwin, icon_str, sizeof(buf), - p_iconstring, use_sandbox, - 0, 0, NULL, NULL); - if (called_emsg > called_emsg_before) - set_string_option_direct((char_u *)"iconstring", -1, - (char_u *)"", OPT_FREE, SID_ERROR); - } + build_stl_str_hl(curwin, icon_str, sizeof(buf), p_iconstring, + (char_u *)"iconstring", 0, 0, 0, NULL, NULL); else #endif icon_str = p_iconstring; @@ -4228,7 +4205,8 @@ build_stl_str_hl( char_u *out, // buffer to write into != NameBuff size_t outlen, // length of out[] char_u *fmt, - int use_sandbox UNUSED, // "fmt" was set insecurely, use sandbox + char_u *opt_name, // option name corresponding to "fmt" + int opt_scope, // scope for "opt_name" int fillchar, int maxwidth, stl_hlrec_T **hltab, // return: HL attributes (can be NULL) @@ -4241,6 +4219,7 @@ build_stl_str_hl( char_u *t; int byteval; #ifdef FEAT_EVAL + int use_sandbox; win_T *save_curwin; buf_T *save_curbuf; int save_VIsual_active; @@ -4276,6 +4255,10 @@ build_stl_str_hl( stl_hlrec_T *sp; int save_redraw_not_allowed = redraw_not_allowed; int save_KeyTyped = KeyTyped; + // TODO: find out why using called_emsg_before makes tests fail, does it + // matter? + // int called_emsg_before = called_emsg; + int did_emsg_before = did_emsg; // When inside update_screen() we do not want redrawing a statusline, // ruler, title, etc. to trigger another redraw, it may cause an endless @@ -4295,10 +4278,11 @@ build_stl_str_hl( } #ifdef FEAT_EVAL - /* - * When the format starts with "%!" then evaluate it as an expression and - * use the result as the actual format string. - */ + // if "fmt" was set insecurely it needs to be evaluated in the sandbox + use_sandbox = was_set_insecurely(opt_name, opt_scope); + + // When the format starts with "%!" then evaluate it as an expression and + // use the result as the actual format string. if (fmt[0] == '%' && fmt[1] == '!') { typval_T tv; @@ -5181,6 +5165,16 @@ build_stl_str_hl( // A user function may reset KeyTyped, restore it. KeyTyped = save_KeyTyped; + // Check for an error. If there is one the display will be messed up and + // might loop redrawing. Avoid that by making the corresponding option + // empty. + // TODO: find out why using called_emsg_before makes tests fail, does it + // matter? + // if (called_emsg > called_emsg_before) + if (did_emsg > did_emsg_before) + set_string_option_direct(opt_name, -1, (char_u *)"", + OPT_FREE | opt_scope, SID_ERROR); + return width; } #endif // FEAT_STL_OPT diff --git a/src/drawscreen.c b/src/drawscreen.c index 5a23d54fd..361f98b24 100644 --- a/src/drawscreen.c +++ b/src/drawscreen.c @@ -573,7 +573,6 @@ win_redr_status(win_T *wp, int ignore_pum UNUSED) redraw_custom_statusline(win_T *wp) { static int entered = FALSE; - int saved_did_emsg = did_emsg; // When called recursively return. This can happen when the statusline // contains an expression that triggers a redraw. @@ -581,18 +580,7 @@ redraw_custom_statusline(win_T *wp) return; entered = TRUE; - did_emsg = FALSE; win_redr_custom(wp, FALSE); - if (did_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); - } - did_emsg |= saved_did_emsg; entered = FALSE; } #endif @@ -673,12 +661,7 @@ win_redr_ruler(win_T *wp, int always, int ignore_pum) #ifdef FEAT_STL_OPT if (*p_ruf) { - int called_emsg_before = called_emsg; - win_redr_custom(wp, TRUE); - if (called_emsg > called_emsg_before) - set_string_option_direct((char_u *)"rulerformat", -1, - (char_u *)"", OPT_FREE, SID_ERROR); return; } #endif diff --git a/src/gui.c b/src/gui.c index 67b4d3e12..dbd8d3fcc 100644 --- a/src/gui.c +++ b/src/gui.c @@ -3763,8 +3763,6 @@ get_tabline_label( opt = (tooltip ? &p_gtt : &p_gtl); if (**opt != NUL) { - int use_sandbox = FALSE; - int called_emsg_before = called_emsg; char_u res[MAXPATHL]; tabpage_T *save_curtab; char_u *opt_name = (char_u *)(tooltip ? "guitabtooltip" @@ -3773,7 +3771,6 @@ get_tabline_label( printer_page_num = tabpage_index(tp); # ifdef FEAT_EVAL set_vim_var_nr(VV_LNUM, printer_page_num); - use_sandbox = was_set_insecurely(opt_name, 0); # endif // It's almost as going to the tabpage, but without autocommands. curtab->tp_firstwin = firstwin; @@ -3788,7 +3785,7 @@ get_tabline_label( curbuf = curwin->w_buffer; // Can't use NameBuff directly, build_stl_str_hl() uses it. - build_stl_str_hl(curwin, res, MAXPATHL, *opt, use_sandbox, + build_stl_str_hl(curwin, res, MAXPATHL, *opt, opt_name, 0, 0, (int)Columns, NULL, NULL); STRCPY(NameBuff, res); @@ -3799,10 +3796,6 @@ get_tabline_label( lastwin = curtab->tp_lastwin; curwin = curtab->tp_curwin; curbuf = curwin->w_buffer; - - if (called_emsg > called_emsg_before) - set_string_option_direct(opt_name, -1, - (char_u *)"", OPT_FREE, SID_ERROR); } // If 'guitablabel'/'guitabtooltip' is not set or the result is empty then diff --git a/src/hardcopy.c b/src/hardcopy.c index dd1f2e071..9d114c587 100644 --- a/src/hardcopy.c +++ b/src/hardcopy.c @@ -471,7 +471,6 @@ prt_header( if (*p_header != NUL) { linenr_T tmp_lnum, tmp_topline, tmp_botline; - int use_sandbox = FALSE; /* * Need to (temporarily) set current line number and first/last line @@ -487,12 +486,8 @@ prt_header( curwin->w_botline = lnum + 63; printer_page_num = pagenum; -# ifdef FEAT_EVAL - use_sandbox = was_set_insecurely((char_u *)"printheader", 0); -# endif - build_stl_str_hl(curwin, tbuf, (size_t)(width + IOSIZE), - p_header, use_sandbox, - ' ', width, NULL, NULL); + build_stl_str_hl(curwin, tbuf, (size_t)(width + IOSIZE), p_header, + (char_u *)"printheader", 0, ' ', width, NULL, NULL); // Reset line numbers curwin->w_cursor.lnum = tmp_lnum; diff --git a/src/proto/buffer.pro b/src/proto/buffer.pro index 094feed9c..3a6102789 100644 --- a/src/proto/buffer.pro +++ b/src/proto/buffer.pro @@ -1,7 +1,7 @@ /* buffer.c */ int get_highest_fnum(void); void buffer_ensure_loaded(buf_T *buf); -int open_buffer(int read_stdin, exarg_T *eap, int flags); +int open_buffer(int read_stdin, exarg_T *eap, int flags_arg); void set_bufref(bufref_T *bufref, buf_T *buf); int bufref_valid(bufref_T *bufref); int buf_valid(buf_T *buf); @@ -48,7 +48,7 @@ void col_print(char_u *buf, size_t buflen, int col, int vcol); void maketitle(void); void resettitle(void); void free_titles(void); -int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, int use_sandbox, int fillchar, int maxwidth, stl_hlrec_T **hltab, stl_hlrec_T **tabtab); +int build_stl_str_hl(win_T *wp, char_u *out, size_t outlen, char_u *fmt, char_u *opt_name, int opt_scope, int fillchar, int maxwidth, stl_hlrec_T **hltab, stl_hlrec_T **tabtab); void get_rel_pos(win_T *wp, char_u *buf, int buflen); char_u *fix_fname(char_u *fname); void fname_expand(buf_T *buf, char_u **ffname, char_u **sfname); diff --git a/src/screen.c b/src/screen.c index 68142f485..15fbe598b 100644 --- a/src/screen.c +++ b/src/screen.c @@ -1284,9 +1284,10 @@ win_redr_custom( char_u buf[MAXPATHL]; char_u *stl; char_u *p; + char_u *opt_name; + int opt_scope = 0; stl_hlrec_T *hltab; stl_hlrec_T *tabtab; - int use_sandbox = FALSE; win_T *ewp; int p_crb_save; @@ -1306,9 +1307,7 @@ win_redr_custom( fillchar = ' '; attr = HL_ATTR(HLF_TPF); maxwidth = Columns; -# ifdef FEAT_EVAL - use_sandbox = was_set_insecurely((char_u *)"tabline", 0); -# endif + opt_name = (char_u *)"tabline"; } else { @@ -1319,6 +1318,7 @@ win_redr_custom( if (draw_ruler) { stl = p_ruf; + opt_name = (char_u *)"rulerformat"; // advance past any leading group spec - implicit in ru_col if (*stl == '%') { @@ -1341,21 +1341,17 @@ win_redr_custom( fillchar = ' '; attr = 0; } - -# ifdef FEAT_EVAL - use_sandbox = was_set_insecurely((char_u *)"rulerformat", 0); -# endif } else { + opt_name = (char_u *)"statusline"; if (*wp->w_p_stl != NUL) + { stl = wp->w_p_stl; + opt_scope = OPT_LOCAL; + } else stl = p_stl; -# ifdef FEAT_EVAL - use_sandbox = was_set_insecurely((char_u *)"statusline", - *wp->w_p_stl == NUL ? 0 : OPT_LOCAL); -# endif } col += wp->w_wincol; @@ -1374,7 +1370,7 @@ win_redr_custom( // might change the option value and free the memory. stl = vim_strsave(stl); width = build_stl_str_hl(ewp, buf, sizeof(buf), - stl, use_sandbox, + stl, opt_name, opt_scope, fillchar, maxwidth, &hltab, &tabtab); vim_free(stl); ewp->w_p_crb = p_crb_save; @@ -4547,18 +4543,7 @@ draw_tabline(void) // Use the 'tabline' option if it's set. if (*p_tal != NUL) - { - int saved_did_emsg = did_emsg; - - // Check for an error. If there is one we would loop in redrawing the - // screen. Avoid that by making 'tabline' empty. - did_emsg = FALSE; win_redr_custom(NULL, FALSE); - if (did_emsg) - set_string_option_direct((char_u *)"tabline", -1, - (char_u *)"", OPT_FREE, SID_ERROR); - did_emsg |= saved_did_emsg; - } else #endif { diff --git a/src/version.c b/src/version.c index a6083ebc2..5d4511dcd 100644 --- a/src/version.c +++ b/src/version.c @@ -695,6 +695,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 844, /**/ 843, /**/ -- 2.40.0