mirror of
https://github.com/zoriya/vim.git
synced 2025-12-19 05:35:17 +00:00
patch 8.0.0365: might free a dict item that wasn't allocated
Problem: Might free a dict item that wasn't allocated.
Solution: Call dictitem_free(). (Nikolai Pavlov) Use this for
b:changedtick.
This commit is contained in:
28
src/buffer.c
28
src/buffer.c
@@ -832,7 +832,6 @@ free_buffer(buf_T *buf)
|
|||||||
free_buffer_stuff(buf, TRUE);
|
free_buffer_stuff(buf, TRUE);
|
||||||
#ifdef FEAT_EVAL
|
#ifdef FEAT_EVAL
|
||||||
unref_var_dict(buf->b_vars);
|
unref_var_dict(buf->b_vars);
|
||||||
buf->b_changedtick = &buf->b_ct_val;
|
|
||||||
#endif
|
#endif
|
||||||
#ifdef FEAT_LUA
|
#ifdef FEAT_LUA
|
||||||
lua_buffer_free(buf);
|
lua_buffer_free(buf);
|
||||||
@@ -874,31 +873,20 @@ free_buffer(buf_T *buf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initializes buf->b_changedtick.
|
* Initializes b:changedtick.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
init_changedtick(buf_T *buf)
|
init_changedtick(buf_T *buf)
|
||||||
{
|
{
|
||||||
#ifdef FEAT_EVAL
|
dictitem_T *di = (dictitem_T *)&buf->b_ct_di;
|
||||||
dictitem_T *di = dictitem_alloc((char_u *)"changedtick");
|
|
||||||
|
|
||||||
if (di != NULL)
|
di->di_flags = DI_FLAGS_FIX | DI_FLAGS_RO;
|
||||||
{
|
|
||||||
di->di_flags |= DI_FLAGS_FIX | DI_FLAGS_RO;
|
|
||||||
di->di_tv.v_type = VAR_NUMBER;
|
di->di_tv.v_type = VAR_NUMBER;
|
||||||
di->di_tv.v_lock = VAR_FIXED;
|
di->di_tv.v_lock = VAR_FIXED;
|
||||||
di->di_tv.vval.v_number = 0;
|
di->di_tv.vval.v_number = 0;
|
||||||
if (dict_add(buf->b_vars, di) == OK)
|
|
||||||
buf->b_changedtick = &di->di_tv.vval.v_number;
|
STRCPY(buf->b_ct_di.di_key, "changedtick");
|
||||||
else
|
(void)dict_add(buf->b_vars, di);
|
||||||
{
|
|
||||||
vim_free(di);
|
|
||||||
buf->b_changedtick = &buf->b_ct_val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
buf->b_changedtick = &buf->b_ct_val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -919,12 +907,12 @@ free_buffer_stuff(
|
|||||||
}
|
}
|
||||||
#ifdef FEAT_EVAL
|
#ifdef FEAT_EVAL
|
||||||
{
|
{
|
||||||
varnumber_T tick = *buf->b_changedtick;
|
varnumber_T tick = CHANGEDTICK(buf);
|
||||||
|
|
||||||
vars_clear(&buf->b_vars->dv_hashtab); /* free all buffer variables */
|
vars_clear(&buf->b_vars->dv_hashtab); /* free all buffer variables */
|
||||||
hash_init(&buf->b_vars->dv_hashtab);
|
hash_init(&buf->b_vars->dv_hashtab);
|
||||||
init_changedtick(buf);
|
init_changedtick(buf);
|
||||||
*buf->b_changedtick = tick;
|
CHANGEDTICK(buf) = tick;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef FEAT_USR_CMDS
|
#ifdef FEAT_USR_CMDS
|
||||||
|
|||||||
@@ -88,8 +88,7 @@ dict_free_contents(dict_T *d)
|
|||||||
* something recursive causing trouble. */
|
* something recursive causing trouble. */
|
||||||
di = HI2DI(hi);
|
di = HI2DI(hi);
|
||||||
hash_remove(&d->dv_hashtab, hi);
|
hash_remove(&d->dv_hashtab, hi);
|
||||||
clear_tv(&di->di_tv);
|
dictitem_free(di);
|
||||||
vim_free(di);
|
|
||||||
--todo;
|
--todo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1668,7 +1668,7 @@ ins_redraw(
|
|||||||
#ifdef FEAT_AUTOCMD
|
#ifdef FEAT_AUTOCMD
|
||||||
/* Trigger TextChangedI if b_changedtick differs. */
|
/* Trigger TextChangedI if b_changedtick differs. */
|
||||||
if (ready && has_textchangedI()
|
if (ready && has_textchangedI()
|
||||||
&& last_changedtick != *curbuf->b_changedtick
|
&& last_changedtick != CHANGEDTICK(curbuf)
|
||||||
# ifdef FEAT_INS_EXPAND
|
# ifdef FEAT_INS_EXPAND
|
||||||
&& !pum_visible()
|
&& !pum_visible()
|
||||||
# endif
|
# endif
|
||||||
@@ -1677,7 +1677,7 @@ ins_redraw(
|
|||||||
if (last_changedtick_buf == curbuf)
|
if (last_changedtick_buf == curbuf)
|
||||||
apply_autocmds(EVENT_TEXTCHANGEDI, NULL, NULL, FALSE, curbuf);
|
apply_autocmds(EVENT_TEXTCHANGEDI, NULL, NULL, FALSE, curbuf);
|
||||||
last_changedtick_buf = curbuf;
|
last_changedtick_buf = curbuf;
|
||||||
last_changedtick = *curbuf->b_changedtick;
|
last_changedtick = CHANGEDTICK(curbuf);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -2550,7 +2550,7 @@ f_diff_hlID(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
|
|||||||
if (lnum < 0) /* ignore type error in {lnum} arg */
|
if (lnum < 0) /* ignore type error in {lnum} arg */
|
||||||
lnum = 0;
|
lnum = 0;
|
||||||
if (lnum != prev_lnum
|
if (lnum != prev_lnum
|
||||||
|| changedtick != *curbuf->b_changedtick
|
|| changedtick != CHANGEDTICK(curbuf)
|
||||||
|| fnum != curbuf->b_fnum)
|
|| fnum != curbuf->b_fnum)
|
||||||
{
|
{
|
||||||
/* New line, buffer, change: need to get the values. */
|
/* New line, buffer, change: need to get the values. */
|
||||||
@@ -2572,7 +2572,7 @@ f_diff_hlID(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
|
|||||||
else
|
else
|
||||||
hlID = (hlf_T)0;
|
hlID = (hlf_T)0;
|
||||||
prev_lnum = lnum;
|
prev_lnum = lnum;
|
||||||
changedtick = *curbuf->b_changedtick;
|
changedtick = CHANGEDTICK(curbuf);
|
||||||
fnum = curbuf->b_fnum;
|
fnum = curbuf->b_fnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3957,7 +3957,7 @@ get_buffer_info(buf_T *buf)
|
|||||||
dict_add_nr_str(dict, "loaded", buf->b_ml.ml_mfp != NULL, NULL);
|
dict_add_nr_str(dict, "loaded", buf->b_ml.ml_mfp != NULL, NULL);
|
||||||
dict_add_nr_str(dict, "listed", buf->b_p_bl, NULL);
|
dict_add_nr_str(dict, "listed", buf->b_p_bl, NULL);
|
||||||
dict_add_nr_str(dict, "changed", bufIsChanged(buf), NULL);
|
dict_add_nr_str(dict, "changed", bufIsChanged(buf), NULL);
|
||||||
dict_add_nr_str(dict, "changedtick", *buf->b_changedtick, NULL);
|
dict_add_nr_str(dict, "changedtick", CHANGEDTICK(buf), NULL);
|
||||||
dict_add_nr_str(dict, "hidden",
|
dict_add_nr_str(dict, "hidden",
|
||||||
buf->b_ml.ml_mfp != NULL && buf->b_nwindows == 0,
|
buf->b_ml.ml_mfp != NULL && buf->b_nwindows == 0,
|
||||||
NULL);
|
NULL);
|
||||||
|
|||||||
@@ -660,7 +660,7 @@ do_exmode(
|
|||||||
need_wait_return = FALSE;
|
need_wait_return = FALSE;
|
||||||
ex_pressedreturn = FALSE;
|
ex_pressedreturn = FALSE;
|
||||||
ex_no_reprint = FALSE;
|
ex_no_reprint = FALSE;
|
||||||
changedtick = *curbuf->b_changedtick;
|
changedtick = CHANGEDTICK(curbuf);
|
||||||
prev_msg_row = msg_row;
|
prev_msg_row = msg_row;
|
||||||
prev_line = curwin->w_cursor.lnum;
|
prev_line = curwin->w_cursor.lnum;
|
||||||
if (improved)
|
if (improved)
|
||||||
@@ -673,7 +673,7 @@ do_exmode(
|
|||||||
lines_left = Rows - 1;
|
lines_left = Rows - 1;
|
||||||
|
|
||||||
if ((prev_line != curwin->w_cursor.lnum
|
if ((prev_line != curwin->w_cursor.lnum
|
||||||
|| changedtick != *curbuf->b_changedtick) && !ex_no_reprint)
|
|| changedtick != CHANGEDTICK(curbuf)) && !ex_no_reprint)
|
||||||
{
|
{
|
||||||
if (curbuf->b_ml.ml_flags & ML_EMPTY)
|
if (curbuf->b_ml.ml_flags & ML_EMPTY)
|
||||||
EMSG(_(e_emptybuf));
|
EMSG(_(e_emptybuf));
|
||||||
|
|||||||
@@ -4924,11 +4924,11 @@ restore_backup:
|
|||||||
{
|
{
|
||||||
unchanged(buf, TRUE);
|
unchanged(buf, TRUE);
|
||||||
#ifdef FEAT_AUTOCMD
|
#ifdef FEAT_AUTOCMD
|
||||||
/* buf->b_changedtick is always incremented in unchanged() but that
|
/* b:changedtick is always incremented in unchanged() but that
|
||||||
* should not trigger a TextChanged event. */
|
* should not trigger a TextChanged event. */
|
||||||
if (last_changedtick + 1 == *buf->b_changedtick
|
if (last_changedtick + 1 == CHANGEDTICK(buf)
|
||||||
&& last_changedtick_buf == buf)
|
&& last_changedtick_buf == buf)
|
||||||
last_changedtick = *buf->b_changedtick;
|
last_changedtick = CHANGEDTICK(buf);
|
||||||
#endif
|
#endif
|
||||||
u_unchanged(buf);
|
u_unchanged(buf);
|
||||||
u_update_save_nr(buf);
|
u_update_save_nr(buf);
|
||||||
|
|||||||
10
src/main.c
10
src/main.c
@@ -1162,15 +1162,15 @@ main_loop(
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef FEAT_AUTOCMD
|
#ifdef FEAT_AUTOCMD
|
||||||
/* Trigger TextChanged if b_changedtick differs. */
|
/* Trigger TextChanged if b:changedtick differs. */
|
||||||
if (!finish_op && has_textchanged()
|
if (!finish_op && has_textchanged()
|
||||||
&& last_changedtick != *curbuf->b_changedtick)
|
&& last_changedtick != CHANGEDTICK(curbuf))
|
||||||
{
|
{
|
||||||
if (last_changedtick_buf == curbuf)
|
if (last_changedtick_buf == curbuf)
|
||||||
apply_autocmds(EVENT_TEXTCHANGED, NULL, NULL,
|
apply_autocmds(EVENT_TEXTCHANGED, NULL, NULL,
|
||||||
FALSE, curbuf);
|
FALSE, curbuf);
|
||||||
last_changedtick_buf = curbuf;
|
last_changedtick_buf = curbuf;
|
||||||
last_changedtick = *curbuf->b_changedtick;
|
last_changedtick = CHANGEDTICK(curbuf);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1388,11 +1388,11 @@ getout(int exitval)
|
|||||||
/* Autocmd must have close the buffer already, skip. */
|
/* Autocmd must have close the buffer already, skip. */
|
||||||
continue;
|
continue;
|
||||||
buf = wp->w_buffer;
|
buf = wp->w_buffer;
|
||||||
if (buf->b_ct_val != -1)
|
if (CHANGEDTICK(buf) != -1)
|
||||||
{
|
{
|
||||||
apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname,
|
apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname,
|
||||||
buf->b_fname, FALSE, buf);
|
buf->b_fname, FALSE, buf);
|
||||||
buf->b_ct_val = -1; /* note that we did it already */
|
CHANGEDTICK(buf) = -1; /* note that we did it already */
|
||||||
/* start all over, autocommands may mess up the lists */
|
/* start all over, autocommands may mess up the lists */
|
||||||
next_tp = first_tabpage;
|
next_tp = first_tabpage;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1649,7 +1649,7 @@ ml_recover(void)
|
|||||||
if (!(curbuf->b_ml.ml_line_count == 2 && *ml_get(1) == NUL))
|
if (!(curbuf->b_ml.ml_line_count == 2 && *ml_get(1) == NUL))
|
||||||
{
|
{
|
||||||
changed_int();
|
changed_int();
|
||||||
++*curbuf->b_changedtick;
|
++CHANGEDTICK(curbuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1663,7 +1663,7 @@ ml_recover(void)
|
|||||||
if (i != 0)
|
if (i != 0)
|
||||||
{
|
{
|
||||||
changed_int();
|
changed_int();
|
||||||
++*curbuf->b_changedtick;
|
++CHANGEDTICK(curbuf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -502,11 +502,11 @@ get_breakindent_win(
|
|||||||
|
|
||||||
/* used cached indent, unless pointer or 'tabstop' changed */
|
/* used cached indent, unless pointer or 'tabstop' changed */
|
||||||
if (prev_line != line || prev_ts != wp->w_buffer->b_p_ts
|
if (prev_line != line || prev_ts != wp->w_buffer->b_p_ts
|
||||||
|| prev_tick != *wp->w_buffer->b_changedtick)
|
|| prev_tick != CHANGEDTICK(wp->w_buffer))
|
||||||
{
|
{
|
||||||
prev_line = line;
|
prev_line = line;
|
||||||
prev_ts = wp->w_buffer->b_p_ts;
|
prev_ts = wp->w_buffer->b_p_ts;
|
||||||
prev_tick = *wp->w_buffer->b_changedtick;
|
prev_tick = CHANGEDTICK(wp->w_buffer);
|
||||||
prev_indent = get_indent_str(line,
|
prev_indent = get_indent_str(line,
|
||||||
(int)wp->w_buffer->b_p_ts, wp->w_p_list);
|
(int)wp->w_buffer->b_p_ts, wp->w_p_list);
|
||||||
}
|
}
|
||||||
@@ -2768,7 +2768,7 @@ changed(void)
|
|||||||
}
|
}
|
||||||
changed_int();
|
changed_int();
|
||||||
}
|
}
|
||||||
++*curbuf->b_changedtick;
|
++CHANGEDTICK(curbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -3195,7 +3195,7 @@ unchanged(
|
|||||||
need_maketitle = TRUE; /* set window title later */
|
need_maketitle = TRUE; /* set window title later */
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
++*buf->b_changedtick;
|
++CHANGEDTICK(buf);
|
||||||
#ifdef FEAT_NETBEANS_INTG
|
#ifdef FEAT_NETBEANS_INTG
|
||||||
netbeans_unmodified(buf);
|
netbeans_unmodified(buf);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1916,9 +1916,10 @@ struct file_buffer
|
|||||||
|
|
||||||
int b_changed; /* 'modified': Set to TRUE if something in the
|
int b_changed; /* 'modified': Set to TRUE if something in the
|
||||||
file has been changed and not written out. */
|
file has been changed and not written out. */
|
||||||
varnumber_T *b_changedtick; /* points into b:changedtick or b_ct_val;
|
dictitem16_T b_ct_di; /* holds the b:changedtick value in
|
||||||
|
b_ct_di.di_tv.vval.v_number;
|
||||||
incremented for each change, also for undo */
|
incremented for each change, also for undo */
|
||||||
varnumber_T b_ct_val; /* fallback for b:changedtick */
|
#define CHANGEDTICK(buf) ((buf)->b_ct_di.di_tv.vval.v_number)
|
||||||
|
|
||||||
int b_saving; /* Set to TRUE if we are in the middle of
|
int b_saving; /* Set to TRUE if we are in the middle of
|
||||||
saving the buffer. */
|
saving the buffer. */
|
||||||
|
|||||||
@@ -516,13 +516,13 @@ syntax_start(win_T *wp, linenr_T lnum)
|
|||||||
*/
|
*/
|
||||||
if (syn_block != wp->w_s
|
if (syn_block != wp->w_s
|
||||||
|| syn_buf != wp->w_buffer
|
|| syn_buf != wp->w_buffer
|
||||||
|| changedtick != *syn_buf->b_changedtick)
|
|| changedtick != CHANGEDTICK(syn_buf))
|
||||||
{
|
{
|
||||||
invalidate_current_state();
|
invalidate_current_state();
|
||||||
syn_buf = wp->w_buffer;
|
syn_buf = wp->w_buffer;
|
||||||
syn_block = wp->w_s;
|
syn_block = wp->w_s;
|
||||||
}
|
}
|
||||||
changedtick = *syn_buf->b_changedtick;
|
changedtick = CHANGEDTICK(syn_buf);
|
||||||
syn_win = wp;
|
syn_win = wp;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -764,6 +764,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
365,
|
||||||
/**/
|
/**/
|
||||||
364,
|
364,
|
||||||
/**/
|
/**/
|
||||||
|
|||||||
Reference in New Issue
Block a user