changeset 31018:9716c7d24c12 v9.0.0844

patch 9.0.0844: handling 'statusline' errors is spread out Commit: https://github.com/vim/vim/commit/7b224fdf4a29f115567d4fc8629c1cef92d8444a Author: Luuk van Baal <luukvbaal@gmail.com> Date: Mon Nov 7 12:16:51 2022 +0000 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)
author Bram Moolenaar <Bram@vim.org>
date Mon, 07 Nov 2022 13:30:04 +0100
parents 99a1b64051b5
children 3cee244c9363
files src/buffer.c src/drawscreen.c src/gui.c src/hardcopy.c src/proto/buffer.pro src/screen.c src/version.c
diffstat 7 files changed, 43 insertions(+), 91 deletions(-) [+]
line wrap: on
line diff
--- 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
--- a/src/drawscreen.c
+++ b/src/drawscreen.c
@@ -573,7 +573,6 @@ win_redr_status(win_T *wp, int ignore_pu
 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, in
 #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
--- 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
--- 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;
--- 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 bufle
 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);
--- 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
     {
--- a/src/version.c
+++ b/src/version.c
@@ -696,6 +696,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    844,
+/**/
     843,
 /**/
     842,