changeset 10952:835604f3c37a v8.0.0365

patch 8.0.0365: might free a dict item that wasn't allocated commit https://github.com/vim/vim/commit/95c526e1f6d76acafee4b21f5701d6d6ac8c4b5f Author: Bram Moolenaar <Bram@vim.org> Date: Sat Feb 25 14:59:34 2017 +0100 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.
author Christian Brabandt <cb@256bit.org>
date Sat, 25 Feb 2017 15:00:05 +0100
parents 32704a1de17c
children 2c46acc89474
files src/buffer.c src/dict.c src/edit.c src/evalfunc.c src/ex_docmd.c src/fileio.c src/main.c src/memline.c src/misc1.c src/structs.h src/syntax.c src/version.c
diffstat 12 files changed, 41 insertions(+), 51 deletions(-) [+]
line wrap: on
line diff
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -832,7 +832,6 @@ free_buffer(buf_T *buf)
     free_buffer_stuff(buf, TRUE);
 #ifdef FEAT_EVAL
     unref_var_dict(buf->b_vars);
-    buf->b_changedtick = &buf->b_ct_val;
 #endif
 #ifdef FEAT_LUA
     lua_buffer_free(buf);
@@ -874,31 +873,20 @@ free_buffer(buf_T *buf)
 }
 
 /*
- * Initializes buf->b_changedtick.
+ * Initializes b:changedtick.
  */
     static void
 init_changedtick(buf_T *buf)
 {
-#ifdef FEAT_EVAL
-    dictitem_T *di = dictitem_alloc((char_u *)"changedtick");
-
-    if (di != NULL)
-    {
-	di->di_flags |= DI_FLAGS_FIX | DI_FLAGS_RO;
-	di->di_tv.v_type = VAR_NUMBER;
-	di->di_tv.v_lock = VAR_FIXED;
-	di->di_tv.vval.v_number = 0;
-	if (dict_add(buf->b_vars, di) == OK)
-	    buf->b_changedtick = &di->di_tv.vval.v_number;
-	else
-	{
-	    vim_free(di);
-	    buf->b_changedtick = &buf->b_ct_val;
-	}
-    }
-    else
-#endif
-	buf->b_changedtick = &buf->b_ct_val;
+    dictitem_T *di = (dictitem_T *)&buf->b_ct_di;
+
+    di->di_flags = DI_FLAGS_FIX | DI_FLAGS_RO;
+    di->di_tv.v_type = VAR_NUMBER;
+    di->di_tv.v_lock = VAR_FIXED;
+    di->di_tv.vval.v_number = 0;
+
+    STRCPY(buf->b_ct_di.di_key, "changedtick");
+    (void)dict_add(buf->b_vars, di);
 }
 
 /*
@@ -919,12 +907,12 @@ free_buffer_stuff(
     }
 #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 */
 	hash_init(&buf->b_vars->dv_hashtab);
 	init_changedtick(buf);
-	*buf->b_changedtick = tick;
+	CHANGEDTICK(buf) = tick;
     }
 #endif
 #ifdef FEAT_USR_CMDS
--- a/src/dict.c
+++ b/src/dict.c
@@ -88,8 +88,7 @@ dict_free_contents(dict_T *d)
 	     * something recursive causing trouble. */
 	    di = HI2DI(hi);
 	    hash_remove(&d->dv_hashtab, hi);
-	    clear_tv(&di->di_tv);
-	    vim_free(di);
+	    dictitem_free(di);
 	    --todo;
 	}
     }
--- a/src/edit.c
+++ b/src/edit.c
@@ -1668,7 +1668,7 @@ ins_redraw(
 #ifdef FEAT_AUTOCMD
     /* Trigger TextChangedI if b_changedtick differs. */
     if (ready && has_textchangedI()
-	    && last_changedtick != *curbuf->b_changedtick
+	    && last_changedtick != CHANGEDTICK(curbuf)
 # ifdef FEAT_INS_EXPAND
 	    && !pum_visible()
 # endif
@@ -1677,7 +1677,7 @@ ins_redraw(
 	if (last_changedtick_buf == curbuf)
 	    apply_autocmds(EVENT_TEXTCHANGEDI, NULL, NULL, FALSE, curbuf);
 	last_changedtick_buf = curbuf;
-	last_changedtick = *curbuf->b_changedtick;
+	last_changedtick = CHANGEDTICK(curbuf);
     }
 #endif
 
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -2550,7 +2550,7 @@ f_diff_hlID(typval_T *argvars UNUSED, ty
     if (lnum < 0)	/* ignore type error in {lnum} arg */
 	lnum = 0;
     if (lnum != prev_lnum
-	    || changedtick != *curbuf->b_changedtick
+	    || changedtick != CHANGEDTICK(curbuf)
 	    || fnum != curbuf->b_fnum)
     {
 	/* New line, buffer, change: need to get the values. */
@@ -2572,7 +2572,7 @@ f_diff_hlID(typval_T *argvars UNUSED, ty
 	else
 	    hlID = (hlf_T)0;
 	prev_lnum = lnum;
-	changedtick = *curbuf->b_changedtick;
+	changedtick = CHANGEDTICK(curbuf);
 	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, "listed", buf->b_p_bl, 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",
 		    buf->b_ml.ml_mfp != NULL && buf->b_nwindows == 0,
 		    NULL);
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -660,7 +660,7 @@ do_exmode(
 	need_wait_return = FALSE;
 	ex_pressedreturn = FALSE;
 	ex_no_reprint = FALSE;
-	changedtick = *curbuf->b_changedtick;
+	changedtick = CHANGEDTICK(curbuf);
 	prev_msg_row = msg_row;
 	prev_line = curwin->w_cursor.lnum;
 	if (improved)
@@ -673,7 +673,7 @@ do_exmode(
 	lines_left = Rows - 1;
 
 	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)
 		EMSG(_(e_emptybuf));
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -4924,11 +4924,11 @@ restore_backup:
     {
 	unchanged(buf, TRUE);
 #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. */
-	if (last_changedtick + 1 == *buf->b_changedtick
+	if (last_changedtick + 1 == CHANGEDTICK(buf)
 					       && last_changedtick_buf == buf)
-	    last_changedtick = *buf->b_changedtick;
+	    last_changedtick = CHANGEDTICK(buf);
 #endif
 	u_unchanged(buf);
 	u_update_save_nr(buf);
--- a/src/main.c
+++ b/src/main.c
@@ -1162,15 +1162,15 @@ main_loop(
 #endif
 
 #ifdef FEAT_AUTOCMD
-	    /* Trigger TextChanged if b_changedtick differs. */
+	    /* Trigger TextChanged if b:changedtick differs. */
 	    if (!finish_op && has_textchanged()
-		    && last_changedtick != *curbuf->b_changedtick)
+		    && last_changedtick != CHANGEDTICK(curbuf))
 	    {
 		if (last_changedtick_buf == curbuf)
 		    apply_autocmds(EVENT_TEXTCHANGED, NULL, NULL,
 							       FALSE, curbuf);
 		last_changedtick_buf = curbuf;
-		last_changedtick = *curbuf->b_changedtick;
+		last_changedtick = CHANGEDTICK(curbuf);
 	    }
 #endif
 
@@ -1388,11 +1388,11 @@ getout(int exitval)
 		    /* Autocmd must have close the buffer already, skip. */
 		    continue;
 		buf = wp->w_buffer;
-		if (buf->b_ct_val != -1)
+		if (CHANGEDTICK(buf) != -1)
 		{
 		    apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname,
 						    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 */
 		    next_tp = first_tabpage;
 		    break;
--- a/src/memline.c
+++ b/src/memline.c
@@ -1649,7 +1649,7 @@ ml_recover(void)
 	if (!(curbuf->b_ml.ml_line_count == 2 && *ml_get(1) == NUL))
 	{
 	    changed_int();
-	    ++*curbuf->b_changedtick;
+	    ++CHANGEDTICK(curbuf);
 	}
     }
     else
@@ -1663,7 +1663,7 @@ ml_recover(void)
 	    if (i != 0)
 	    {
 		changed_int();
-		++*curbuf->b_changedtick;
+		++CHANGEDTICK(curbuf);
 		break;
 	    }
 	}
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -502,11 +502,11 @@ get_breakindent_win(
 
     /* used cached indent, unless pointer or 'tabstop' changed */
     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_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,
 				     (int)wp->w_buffer->b_p_ts, wp->w_p_list);
     }
@@ -2768,7 +2768,7 @@ changed(void)
 	}
 	changed_int();
     }
-    ++*curbuf->b_changedtick;
+    ++CHANGEDTICK(curbuf);
 }
 
 /*
@@ -3195,7 +3195,7 @@ unchanged(
 	need_maketitle = TRUE;	    /* set window title later */
 #endif
     }
-    ++*buf->b_changedtick;
+    ++CHANGEDTICK(buf);
 #ifdef FEAT_NETBEANS_INTG
     netbeans_unmodified(buf);
 #endif
--- a/src/structs.h
+++ b/src/structs.h
@@ -1916,9 +1916,10 @@ struct file_buffer
 
     int		b_changed;	/* 'modified': Set to TRUE if something in the
 				   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 */
-    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
 				   saving the buffer. */
--- a/src/syntax.c
+++ b/src/syntax.c
@@ -516,13 +516,13 @@ syntax_start(win_T *wp, linenr_T lnum)
      */
     if (syn_block != wp->w_s
 	    || syn_buf != wp->w_buffer
-	    || changedtick != *syn_buf->b_changedtick)
+	    || changedtick != CHANGEDTICK(syn_buf))
     {
 	invalidate_current_state();
 	syn_buf = wp->w_buffer;
 	syn_block = wp->w_s;
     }
-    changedtick = *syn_buf->b_changedtick;
+    changedtick = CHANGEDTICK(syn_buf);
     syn_win = wp;
 
     /*
--- a/src/version.c
+++ b/src/version.c
@@ -765,6 +765,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    365,
+/**/
     364,
 /**/
     363,