Skip to content

Commit

Permalink
updated for version 7.3.893
Browse files Browse the repository at this point in the history
Problem:    Crash when using b:, w: or t: after closing the buffer, window or
            tabpage.
Solution:   Allocate the dictionary instead of having it part of the
            buffer/window/tabpage struct. (Yukihiro Nakadaira)
  • Loading branch information
brammool committed Apr 15, 2013
1 parent 07219f9 commit 429fa85
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 81 deletions.
22 changes: 16 additions & 6 deletions src/buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,9 @@ free_buffer(buf)
buf_T *buf;
{
free_buffer_stuff(buf, TRUE);
#ifdef FEAT_EVAL
unref_var_dict(buf->b_vars);
#endif
#ifdef FEAT_LUA
lua_buffer_free(buf);
#endif
Expand Down Expand Up @@ -689,8 +692,8 @@ free_buffer_stuff(buf, free_options)
#endif
}
#ifdef FEAT_EVAL
vars_clear(&buf->b_vars.dv_hashtab); /* free all internal variables */
hash_init(&buf->b_vars.dv_hashtab);
vars_clear(&buf->b_vars->dv_hashtab); /* free all internal variables */
hash_init(&buf->b_vars->dv_hashtab);
#endif
#ifdef FEAT_USR_CMDS
uc_clear(&buf->b_ucmds); /* clear local user commands */
Expand Down Expand Up @@ -1694,6 +1697,17 @@ buflist_new(ffname, sfname, lnum, flags)
vim_free(ffname);
return NULL;
}
#ifdef FEAT_EVAL
/* init b: variables */
buf->b_vars = dict_alloc();
if (buf->b_vars == NULL)
{
vim_free(ffname);
vim_free(buf);
return NULL;
}
init_var_dict(buf->b_vars, &buf->b_bufvar, VAR_SCOPE);
#endif
}

if (ffname != NULL)
Expand Down Expand Up @@ -1778,10 +1792,6 @@ buflist_new(ffname, sfname, lnum, flags)
buf->b_wininfo->wi_fpos.lnum = lnum;
buf->b_wininfo->wi_win = curwin;

#ifdef FEAT_EVAL
/* init b: variables */
init_var_dict(&buf->b_vars, &buf->b_bufvar, VAR_SCOPE);
#endif
#ifdef FEAT_SYN_HL
hash_init(&buf->b_s.b_keywtab);
hash_init(&buf->b_s.b_keywtab_ic);
Expand Down
45 changes: 29 additions & 16 deletions src/eval.c
Original file line number Diff line number Diff line change
Expand Up @@ -2131,7 +2131,7 @@ list_buf_vars(first)
{
char_u numbuf[NUMBUFLEN];

list_hashtable_vars(&curbuf->b_vars.dv_hashtab, (char_u *)"b:",
list_hashtable_vars(&curbuf->b_vars->dv_hashtab, (char_u *)"b:",
TRUE, first);

sprintf((char *)numbuf, "%ld", (long)curbuf->b_changedtick);
Expand All @@ -2146,7 +2146,7 @@ list_buf_vars(first)
list_win_vars(first)
int *first;
{
list_hashtable_vars(&curwin->w_vars.dv_hashtab,
list_hashtable_vars(&curwin->w_vars->dv_hashtab,
(char_u *)"w:", TRUE, first);
}

Expand All @@ -2158,7 +2158,7 @@ list_win_vars(first)
list_tab_vars(first)
int *first;
{
list_hashtable_vars(&curtab->tp_vars.dv_hashtab,
list_hashtable_vars(&curtab->tp_vars->dv_hashtab,
(char_u *)"t:", TRUE, first);
}
#endif
Expand Down Expand Up @@ -3948,7 +3948,7 @@ get_user_var_name(xp, idx)
}

/* b: variables */
ht = &curbuf->b_vars.dv_hashtab;
ht = &curbuf->b_vars->dv_hashtab;
if (bdone < ht->ht_used)
{
if (bdone++ == 0)
Expand All @@ -3966,7 +3966,7 @@ get_user_var_name(xp, idx)
}

/* w: variables */
ht = &curwin->w_vars.dv_hashtab;
ht = &curwin->w_vars->dv_hashtab;
if (wdone < ht->ht_used)
{
if (wdone++ == 0)
Expand All @@ -3980,7 +3980,7 @@ get_user_var_name(xp, idx)

#ifdef FEAT_WINDOWS
/* t: variables */
ht = &curtab->tp_vars.dv_hashtab;
ht = &curtab->tp_vars->dv_hashtab;
if (tdone < ht->ht_used)
{
if (tdone++ == 0)
Expand Down Expand Up @@ -6787,16 +6787,16 @@ garbage_collect()

/* buffer-local variables */
for (buf = firstbuf; buf != NULL; buf = buf->b_next)
set_ref_in_ht(&buf->b_vars.dv_hashtab, copyID);
set_ref_in_item(&buf->b_bufvar.di_tv, copyID);

/* window-local variables */
FOR_ALL_TAB_WINDOWS(tp, wp)
set_ref_in_ht(&wp->w_vars.dv_hashtab, copyID);
set_ref_in_item(&wp->w_winvar.di_tv, copyID);

#ifdef FEAT_WINDOWS
/* tabpage-local variables */
for (tp = first_tabpage; tp != NULL; tp = tp->tp_next)
set_ref_in_ht(&tp->tp_vars.dv_hashtab, copyID);
set_ref_in_item(&tp->tp_winvar.di_tv, copyID);
#endif

/* global variables */
Expand Down Expand Up @@ -11156,7 +11156,7 @@ f_getbufvar(argvars, rettv)
* find_var_in_ht(). */
varname = (char_u *)"b:" + 2;
/* look up the variable */
v = find_var_in_ht(&curbuf->b_vars.dv_hashtab, varname, FALSE);
v = find_var_in_ht(&curbuf->b_vars->dv_hashtab, varname, FALSE);
if (v != NULL)
copy_tv(&v->di_tv, rettv);
}
Expand Down Expand Up @@ -11779,7 +11779,7 @@ f_gettabvar(argvars, rettv)
if (tp != NULL && varname != NULL)
{
/* look up the variable */
v = find_var_in_ht(&tp->tp_vars.dv_hashtab, varname, FALSE);
v = find_var_in_ht(&tp->tp_vars->dv_hashtab, varname, FALSE);
if (v != NULL)
copy_tv(&v->di_tv, rettv);
else if (argvars[2].v_type != VAR_UNKNOWN)
Expand Down Expand Up @@ -11935,7 +11935,7 @@ getwinvar(argvars, rettv, off)
* find_var_in_ht(). */
varname = (char_u *)"w:" + 2;
/* look up the variable */
v = find_var_in_ht(&win->w_vars.dv_hashtab, varname, FALSE);
v = find_var_in_ht(&win->w_vars->dv_hashtab, varname, FALSE);
if (v != NULL)
copy_tv(&v->di_tv, rettv);
}
Expand Down Expand Up @@ -14333,7 +14333,7 @@ f_mode(argvars, rettv)
rettv->v_type = VAR_STRING;
}

#ifdef FEAT_MZSCHEME
#if defined(FEAT_MZSCHEME) || defined(PROTO)
/*
* "mzeval()" function
*/
Expand Down Expand Up @@ -20134,12 +20134,12 @@ find_var_ht(name, varname)
|| vim_strchr(name + 2, AUTOLOAD_CHAR) != NULL)
return NULL;
if (*name == 'b') /* buffer variable */
return &curbuf->b_vars.dv_hashtab;
return &curbuf->b_vars->dv_hashtab;
if (*name == 'w') /* window variable */
return &curwin->w_vars.dv_hashtab;
return &curwin->w_vars->dv_hashtab;
#ifdef FEAT_WINDOWS
if (*name == 't') /* tab page variable */
return &curtab->tp_vars.dv_hashtab;
return &curtab->tp_vars->dv_hashtab;
#endif
if (*name == 'v') /* v: variable */
return &vimvarht;
Expand Down Expand Up @@ -20228,6 +20228,19 @@ init_var_dict(dict, dict_var, scope)
dict_var->di_key[0] = NUL;
}

/*
* Unreference a dictionary initialized by init_var_dict().
*/
void
unref_var_dict(dict)
dict_T *dict;
{
/* Now the dict needs to be freed if no one else is using it, go back to
* normal reference counting. */
dict->dv_refcount -= DO_NOT_FREE_CNT - 1;
dict_unref(dict);
}

/*
* Clean up a list of internal variables.
* Frees all allocated variables and the value they contain.
Expand Down
4 changes: 2 additions & 2 deletions src/fileio.c
Original file line number Diff line number Diff line change
Expand Up @@ -8955,8 +8955,8 @@ aucmd_restbuf(aco)
/* Hmm, original window disappeared. Just use the first one. */
curwin = firstwin;
# ifdef FEAT_EVAL
vars_clear(&aucmd_win->w_vars.dv_hashtab); /* free all w: variables */
hash_init(&aucmd_win->w_vars.dv_hashtab); /* re-use the hashtab */
vars_clear(&aucmd_win->w_vars->dv_hashtab); /* free all w: variables */
hash_init(&aucmd_win->w_vars->dv_hashtab); /* re-use the hashtab */
# endif
#else
curwin = aco->save_curwin;
Expand Down
3 changes: 2 additions & 1 deletion src/proto/eval.pro
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ list_T *eval_spell_expr __ARGS((char_u *badword, char_u *expr));
int get_spellword __ARGS((list_T *list, char_u **pp));
typval_T *eval_expr __ARGS((char_u *arg, char_u **nextcmd));
int call_vim_function __ARGS((char_u *func, int argc, char_u **argv, int safe, int str_arg_only, typval_T *rettv));
void *call_func_retstr __ARGS((char_u *func, int argc, char_u **argv, int safe));
long call_func_retnr __ARGS((char_u *func, int argc, char_u **argv, int safe));
void *call_func_retstr __ARGS((char_u *func, int argc, char_u **argv, int safe));
void *call_func_retlist __ARGS((char_u *func, int argc, char_u **argv, int safe));
void *save_funccal __ARGS((void));
void restore_funccal __ARGS((void *vfc));
Expand Down Expand Up @@ -95,6 +95,7 @@ char_u *get_tv_string_chk __ARGS((typval_T *varp));
char_u *get_var_value __ARGS((char_u *name));
void new_script_vars __ARGS((scid_T id));
void init_var_dict __ARGS((dict_T *dict, dictitem_T *dict_var, int scope));
void unref_var_dict __ARGS((dict_T *dict));
void vars_clear __ARGS((hashtab_T *ht));
void copy_tv __ARGS((typval_T *from, typval_T *to));
void ex_echo __ARGS((exarg_T *eap));
Expand Down
6 changes: 3 additions & 3 deletions src/structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1611,7 +1611,7 @@ struct file_buffer

#ifdef FEAT_EVAL
dictitem_T b_bufvar; /* variable for "b:" Dictionary */
dict_T b_vars; /* internal variables, local to buffer */
dict_T *b_vars; /* internal variables, local to buffer */
#endif

#if defined(FEAT_BEVAL) && defined(FEAT_EVAL)
Expand Down Expand Up @@ -1757,7 +1757,7 @@ struct tabpage_S
frame_T *(tp_snapshot[SNAP_COUNT]); /* window layout snapshots */
#ifdef FEAT_EVAL
dictitem_T tp_winvar; /* variable for "t:" Dictionary */
dict_T tp_vars; /* internal variables, local to tab page */
dict_T *tp_vars; /* internal variables, local to tab page */
#endif
};

Expand Down Expand Up @@ -2080,7 +2080,7 @@ struct window_S

#ifdef FEAT_EVAL
dictitem_T w_winvar; /* variable for "w:" Dictionary */
dict_T w_vars; /* internal variables, local to window */
dict_T *w_vars; /* internal variables, local to window */
#endif

#if defined(FEAT_RIGHTLEFT) && defined(FEAT_FKMAP)
Expand Down
2 changes: 2 additions & 0 deletions src/version.c
Original file line number Diff line number Diff line change
Expand Up @@ -728,6 +728,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
/**/
893,
/**/
892,
/**/
Expand Down
Loading

0 comments on commit 429fa85

Please sign in to comment.