# HG changeset patch # User Bram Moolenaar # Date 1411129596 -7200 # Node ID 63121fdd093ff71081725d5495337ea45d38daab # Parent f3c980ab39a367caa0e63d3bc881bb2d02f4f18a updated for version 7.4.446 Problem: In some situations, when setting up an environment to trigger an autocommand, the environment is not properly restored. Solution: Check the return value of switch_win() and call restore_win() always. (Daniel Hahler) diff --git a/src/eval.c b/src/eval.c --- a/src/eval.c +++ b/src/eval.c @@ -12086,15 +12086,17 @@ f_gettabvar(argvars, rettv) { /* Set tp to be our tabpage, temporarily. Also set the window to the * first window in the tabpage, otherwise the window is not valid. */ - switch_win(&oldcurwin, &oldtabpage, tp->tp_firstwin, tp, TRUE); - - /* look up the variable */ - /* Let gettabvar({nr}, "") return the "t:" dictionary. */ - v = find_var_in_ht(&tp->tp_vars->dv_hashtab, 't', varname, FALSE); - if (v != NULL) - { - copy_tv(&v->di_tv, rettv); - done = TRUE; + if (switch_win(&oldcurwin, &oldtabpage, tp->tp_firstwin, tp, TRUE) + == OK) + { + /* look up the variable */ + /* Let gettabvar({nr}, "") return the "t:" dictionary. */ + v = find_var_in_ht(&tp->tp_vars->dv_hashtab, 't', varname, FALSE); + if (v != NULL) + { + copy_tv(&v->di_tv, rettv); + done = TRUE; + } } /* restore previous notion of curwin */ @@ -12233,22 +12235,24 @@ getwinvar(argvars, rettv, off) { /* Set curwin to be our win, temporarily. Also set the tabpage, * otherwise the window is not valid. */ - switch_win(&oldcurwin, &oldtabpage, win, tp, TRUE); - - if (*varname == '&') /* window-local-option */ - { - if (get_option_tv(&varname, rettv, 1) == OK) - done = TRUE; - } - else - { - /* Look up the variable. */ - /* Let getwinvar({nr}, "") return the "w:" dictionary. */ - v = find_var_in_ht(&win->w_vars->dv_hashtab, 'w', varname, FALSE); - if (v != NULL) - { - copy_tv(&v->di_tv, rettv); - done = TRUE; + if (switch_win(&oldcurwin, &oldtabpage, win, tp, TRUE) == OK) + { + if (*varname == '&') /* window-local-option */ + { + if (get_option_tv(&varname, rettv, 1) == OK) + done = TRUE; + } + else + { + /* Look up the variable. */ + /* Let getwinvar({nr}, "") return the "w:" dictionary. */ + v = find_var_in_ht(&win->w_vars->dv_hashtab, 'w', + varname, FALSE); + if (v != NULL) + { + copy_tv(&v->di_tv, rettv); + done = TRUE; + } } } @@ -17252,34 +17256,33 @@ setwinvar(argvars, rettv, off) if (win != NULL && varname != NULL && varp != NULL) { #ifdef FEAT_WINDOWS - if (switch_win(&save_curwin, &save_curtab, win, tp, TRUE) == FAIL) - return; -#endif - - if (*varname == '&') - { - long numval; - char_u *strval; - int error = FALSE; - - ++varname; - numval = get_tv_number_chk(varp, &error); - strval = get_tv_string_buf_chk(varp, nbuf); - if (!error && strval != NULL) - set_option_value(varname, numval, strval, OPT_LOCAL); - } - else - { - winvarname = alloc((unsigned)STRLEN(varname) + 3); - if (winvarname != NULL) - { - STRCPY(winvarname, "w:"); - STRCPY(winvarname + 2, varname); - set_var(winvarname, varp, TRUE); - vim_free(winvarname); - } - } - + if (switch_win(&save_curwin, &save_curtab, win, tp, TRUE) == OK) +#endif + { + if (*varname == '&') + { + long numval; + char_u *strval; + int error = FALSE; + + ++varname; + numval = get_tv_number_chk(varp, &error); + strval = get_tv_string_buf_chk(varp, nbuf); + if (!error && strval != NULL) + set_option_value(varname, numval, strval, OPT_LOCAL); + } + else + { + winvarname = alloc((unsigned)STRLEN(varname) + 3); + if (winvarname != NULL) + { + STRCPY(winvarname, "w:"); + STRCPY(winvarname + 2, varname); + set_var(winvarname, varp, TRUE); + vim_free(winvarname); + } + } + } #ifdef FEAT_WINDOWS restore_win(save_curwin, save_curtab, TRUE); #endif diff --git a/src/misc2.c b/src/misc2.c --- a/src/misc2.c +++ b/src/misc2.c @@ -1040,7 +1040,8 @@ free_all_mem() entered = TRUE; # ifdef FEAT_AUTOCMD - block_autocmds(); /* don't want to trigger autocommands here */ + /* Don't want to trigger autocommands from here on. */ + block_autocmds(); # endif # ifdef FEAT_WINDOWS diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -742,6 +742,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 446, +/**/ 445, /**/ 444, diff --git a/src/window.c b/src/window.c --- a/src/window.c +++ b/src/window.c @@ -1271,7 +1271,7 @@ win_init(newp, oldp, flags) } /* - * Initialize window "newp" from window"old". + * Initialize window "newp" from window "old". * Only the essential things are copied. */ static void @@ -6662,8 +6662,8 @@ restore_snapshot_rec(sn, fr) || defined(PROTO) /* * Set "win" to be the curwin and "tp" to be the current tab page. - * restore_win() MUST be called to undo. - * No autocommands will be executed. + * restore_win() MUST be called to undo, also when FAIL is returned. + * No autocommands will be executed until restore_win() is called. * When "no_display" is TRUE the display won't be affected, no redraw is * triggered, another tabpage access is limited. * Returns FAIL if switching to "win" failed. @@ -6696,12 +6696,7 @@ switch_win(save_curwin, save_curtab, win goto_tabpage_tp(tp, FALSE, FALSE); } if (!win_valid(win)) - { -# ifdef FEAT_AUTOCMD - unblock_autocmds(); -# endif return FAIL; - } curwin = win; curbuf = curwin->w_buffer; # endif