vim-patch: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)

https://code.google.com/p/vim/source/detail?r=v7-4-446
This commit is contained in:
Pavel Platto 2015-01-20 20:03:39 +02:00
parent da43f70ba7
commit 85f342a110
4 changed files with 30 additions and 33 deletions

View File

@ -9604,7 +9604,7 @@ static void f_gettabvar(typval_T *argvars, typval_T *rettv)
tabpage_T *tp, *oldtabpage; tabpage_T *tp, *oldtabpage;
dictitem_T *v; dictitem_T *v;
char_u *varname; char_u *varname;
int done = FALSE; bool done = false;
rettv->v_type = VAR_STRING; rettv->v_type = VAR_STRING;
rettv->vval.v_string = NULL; rettv->vval.v_string = NULL;
@ -9614,14 +9614,14 @@ static void f_gettabvar(typval_T *argvars, typval_T *rettv)
if (tp != NULL && varname != NULL) { if (tp != NULL && varname != NULL) {
/* Set tp to be our tabpage, temporarily. Also set the window to the /* Set tp to be our tabpage, temporarily. Also set the window to the
* first window in the tabpage, otherwise the window is not valid. */ * first window in the tabpage, otherwise the window is not valid. */
switch_win(&oldcurwin, &oldtabpage, tp->tp_firstwin, tp, TRUE); if (switch_win(&oldcurwin, &oldtabpage, tp->tp_firstwin, tp, TRUE) == OK) {
// look up the variable
/* look up the variable */ // Let gettabvar({nr}, "") return the "t:" dictionary.
/* Let gettabvar({nr}, "") return the "t:" dictionary. */ v = find_var_in_ht(&tp->tp_vars->dv_hashtab, 't', varname, FALSE);
v = find_var_in_ht(&tp->tp_vars->dv_hashtab, 't', varname, FALSE); if (v != NULL) {
if (v != NULL) { copy_tv(&v->di_tv, rettv);
copy_tv(&v->di_tv, rettv); done = true;
done = TRUE; }
} }
/* restore previous notion of curwin */ /* restore previous notion of curwin */
@ -9712,7 +9712,7 @@ getwinvar (
dictitem_T *v; dictitem_T *v;
tabpage_T *tp = NULL; tabpage_T *tp = NULL;
tabpage_T *oldtabpage = NULL; tabpage_T *oldtabpage = NULL;
int done = FALSE; bool done = false;
if (off == 1) if (off == 1)
tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL)); tp = find_tabpage((int)get_tv_number_chk(&argvars[0], NULL));
@ -9728,18 +9728,18 @@ getwinvar (
if (win != NULL && varname != NULL) { if (win != NULL && varname != NULL) {
/* Set curwin to be our win, temporarily. Also set the tabpage, /* Set curwin to be our win, temporarily. Also set the tabpage,
* otherwise the window is not valid. */ * otherwise the window is not valid. */
switch_win(&oldcurwin, &oldtabpage, win, tp, TRUE); if (switch_win(&oldcurwin, &oldtabpage, win, tp, TRUE) == OK) {
if (*varname == '&') { /* window-local-option */
if (*varname == '&') { /* window-local-option */ if (get_option_tv(&varname, rettv, 1) == OK)
if (get_option_tv(&varname, rettv, 1) == OK) done = true;
done = TRUE; } else {
} else { // Look up the variable.
/* Look up the variable. */ // Let getwinvar({nr}, "") return the "w:" dictionary.
/* Let getwinvar({nr}, "") return the "w:" dictionary. */ v = find_var_in_ht(&win->w_vars->dv_hashtab, 'w', varname, FALSE);
v = find_var_in_ht(&win->w_vars->dv_hashtab, 'w', varname, FALSE); if (v != NULL) {
if (v != NULL) { copy_tv(&v->di_tv, rettv);
copy_tv(&v->di_tv, rettv); done = true;
done = TRUE; }
} }
} }
@ -13494,10 +13494,8 @@ static void setwinvar(typval_T *argvars, typval_T *rettv, int off)
varname = get_tv_string_chk(&argvars[off + 1]); varname = get_tv_string_chk(&argvars[off + 1]);
varp = &argvars[off + 2]; varp = &argvars[off + 2];
if (win != NULL && varname != NULL && varp != NULL) { if (win != NULL && varname != NULL && varp != NULL
if (switch_win(&save_curwin, &save_curtab, win, tp, TRUE) == FAIL) && switch_win(&save_curwin, &save_curtab, win, tp, TRUE) == OK) {
return;
if (*varname == '&') { if (*varname == '&') {
long numval; long numval;
char_u *strval; char_u *strval;
@ -13515,7 +13513,6 @@ static void setwinvar(typval_T *argvars, typval_T *rettv, int off)
set_var(winvarname, varp, TRUE); set_var(winvarname, varp, TRUE);
free(winvarname); free(winvarname);
} }
restore_win(save_curwin, save_curtab, TRUE); restore_win(save_curwin, save_curtab, TRUE);
} }
} }

View File

@ -489,7 +489,8 @@ void free_all_mem(void)
return; return;
entered = true; entered = true;
block_autocmds(); /* don't want to trigger autocommands here */ // Don't want to trigger autocommands from here on.
block_autocmds();
/* Close all tabs and windows. Reset 'equalalways' to avoid redraws. */ /* Close all tabs and windows. Reset 'equalalways' to avoid redraws. */
p_ea = FALSE; p_ea = FALSE;

View File

@ -299,7 +299,7 @@ static int included_patches[] = {
449, 449,
//448 NA //448 NA
447, 447,
//446, 446,
//445, //445,
444, 444,
//443 NA //443 NA

View File

@ -1024,7 +1024,7 @@ static void win_init(win_T *newp, win_T *oldp, int flags)
} }
/* /*
* Initialize window "newp" from window"old". * Initialize window "newp" from window "old".
* Only the essential things are copied. * Only the essential things are copied.
*/ */
static void win_init_some(win_T *newp, win_T *oldp) static void win_init_some(win_T *newp, win_T *oldp)
@ -5190,8 +5190,8 @@ static win_T *restore_snapshot_rec(frame_T *sn, frame_T *fr)
/* /*
* Set "win" to be the curwin and "tp" to be the current tab page. * Set "win" to be the curwin and "tp" to be the current tab page.
* restore_win() MUST be called to undo. * restore_win() MUST be called to undo, also when FAIL is returned.
* No autocommands will be executed. * No autocommands will be executed until restore_win() is called.
* When "no_display" is TRUE the display won't be affected, no redraw is * When "no_display" is TRUE the display won't be affected, no redraw is
* triggered, another tabpage access is limited. * triggered, another tabpage access is limited.
* Returns FAIL if switching to "win" failed. * Returns FAIL if switching to "win" failed.
@ -5212,7 +5212,6 @@ int switch_win(win_T **save_curwin, tabpage_T **save_curtab, win_T *win, tabpage
goto_tabpage_tp(tp, FALSE, FALSE); goto_tabpage_tp(tp, FALSE, FALSE);
} }
if (!win_valid(win)) { if (!win_valid(win)) {
unblock_autocmds();
return FAIL; return FAIL;
} }
curwin = win; curwin = win;