]> granicus.if.org Git - vim/commitdiff
patch 8.0.0365: might free a dict item that wasn't allocated v8.0.0365
authorBram Moolenaar <Bram@vim.org>
Sat, 25 Feb 2017 13:59:34 +0000 (14:59 +0100)
committerBram Moolenaar <Bram@vim.org>
Sat, 25 Feb 2017 13:59:34 +0000 (14:59 +0100)
Problem:    Might free a dict item that wasn't allocated.
Solution:   Call dictitem_free(). (Nikolai Pavlov)  Use this for
            b:changedtick.

12 files changed:
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

index b394d8e6c231d00ce3fb03fb93285012eb234293..73af50a7a2113b01450b47c84a9e0ca147499f66 100644 (file)
@@ -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");
+    dictitem_T *di = (dictitem_T *)&buf->b_ct_di;
 
-    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;
+    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
index 07d10008c654a1672f49e79dd0b80cb9e786d614..70743059e4583573ad775dd3dbce8354ac584c58 100644 (file)
@@ -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;
        }
     }
index c4e7ddd189cdcf7b66638c847850ee52aa7b90ef..9a824322ffd4fa798a1fa8646d38d25859a7ffc0 100644 (file)
@@ -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
 
index 1307d1203f8bbdb1d2c494cdd88e62f1a97097fd..52527bc897f5c04e2733dce0f63c32bf6345f9be 100644 (file)
@@ -2550,7 +2550,7 @@ f_diff_hlID(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
     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, typval_T *rettv UNUSED)
        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);
index 5ad094ca81f488d3fcd2c3c54f31cd49288c41d4..4c52cdf808961562a507812fb9ddbf189f0b6fcd 100644 (file)
@@ -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));
index 73baecc037bdeeb8f6b64fb393d13a62f5b0bdf6..2001c0d9a5ec4383de20d59895a8be08e19777ec 100644 (file)
@@ -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);
index ff173af7ef8a6f2292b96df334678885a6283162..387221c9d704752cc3e7f8e97fc69e5cacc55794 100644 (file)
@@ -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;
index df799b1b25cb34442e83d2b1ac0896a1700f021a..01e8d5ba3761b4a64cbe9b2f1f91a850332f147d 100644 (file)
@@ -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;
            }
        }
index 9f867266f39e13e3390ffa473249295154194f61..fbb1081a507f782688278c447e17d1d6f141d285 100644 (file)
@@ -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
index 23ce826a320dc3d014f46ba6965426dee725d743..1e1b1da82cf702688bd9e2efe5192bca345f3769 100644 (file)
@@ -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. */
index 6b9019020ac81cc6991ade6397215a384dd37e0c..0d9cd2cedc7648a3abb98ad0750d9cfb970ac164 100644 (file)
@@ -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;
 
     /*
index ffacb9ae810f52b18667245872df440408691523..d80a0ea0113539a70973fe5982fc14c993a9de69 100644 (file)
@@ -764,6 +764,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    365,
 /**/
     364,
 /**/