]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
updated for version 7.3.893 v7.3.893
authorBram Moolenaar <Bram@vim.org>
Mon, 15 Apr 2013 10:27:36 +0000 (12:27 +0200)
committerBram Moolenaar <Bram@vim.org>
Mon, 15 Apr 2013 10:27:36 +0000 (12:27 +0200)
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)

src/buffer.c
src/eval.c
src/fileio.c
src/proto/eval.pro
src/structs.h
src/version.c
src/window.c

index 2a9fe4d12307453aad88ef96df2a0da076b53dba..5ee6299901b973ca537d042db62771bd4e4dba1e 100644 (file)
@@ -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
@@ -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 */
@@ -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)
@@ -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);
index 49120b8c047370367b6785b8e435281131075ba2..5f9ddb4d7a149889eddc810cb1a4eee1244f357c 100644 (file)
@@ -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);
@@ -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);
 }
 
@@ -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
@@ -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)
@@ -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)
@@ -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)
@@ -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 */
@@ -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);
        }
@@ -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)
@@ -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);
        }
@@ -14333,7 +14333,7 @@ f_mode(argvars, rettv)
     rettv->v_type = VAR_STRING;
 }
 
-#ifdef FEAT_MZSCHEME
+#if defined(FEAT_MZSCHEME) || defined(PROTO)
 /*
  * "mzeval()" function
  */
@@ -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;
@@ -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.
index 6e89b888c3e91b0bf6657feddf16b5901e5c0f55..251d1554475a72e48980137739d17808e7fb214d 100644 (file)
@@ -8955,8 +8955,8 @@ win_found:
            /* 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;
index 5ad27aa5d92af51d3bdb44dbdf611d3c0713a0cb..b23700d707869f83102d3d7cae33cebd26249af9 100644 (file)
@@ -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));
@@ -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));
index 36440c3c2ac341337b988354084de5da39f7bfc1..630512956e1c790943880bf7d1a74f5cb4527a5f 100644 (file)
@@ -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)
@@ -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
 };
 
@@ -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)
index 8683cec45a2b5eb1692aaa3121e10b1bef7aed96..309114b33bc99d04c9f08ca167b07b8224cc931c 100644 (file)
@@ -728,6 +728,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    893,
 /**/
     892,
 /**/
index 1a09c9145c57399b52e410c737955263a2d286ac..fadbb925924c2f76b0cd66a53c897dd232dc5732 100644 (file)
@@ -3457,25 +3457,35 @@ win_init_size()
 alloc_tabpage()
 {
     tabpage_T  *tp;
+# ifdef FEAT_GUI
+    int                i;
+# endif
+
 
     tp = (tabpage_T *)alloc_clear((unsigned)sizeof(tabpage_T));
-    if (tp != NULL)
+    if (tp == NULL)
+       return NULL;
+
+# ifdef FEAT_EVAL
+    /* init t: variables */
+    tp->tp_vars = dict_alloc();
+    if (tp->tp_vars == NULL)
     {
-# ifdef FEAT_GUI
-       int     i;
+       vim_free(tp);
+       return NULL;
+    }
+    init_var_dict(tp->tp_vars, &tp->tp_winvar, VAR_SCOPE);
+# endif
 
-       for (i = 0; i < 3; i++)
-           tp->tp_prev_which_scrollbars[i] = -1;
+# ifdef FEAT_GUI
+    for (i = 0; i < 3; i++)
+       tp->tp_prev_which_scrollbars[i] = -1;
 # endif
 # ifdef FEAT_DIFF
-       tp->tp_diff_invalid = TRUE;
+    tp->tp_diff_invalid = TRUE;
 # endif
-#ifdef FEAT_EVAL
-       /* init t: variables */
-       init_var_dict(&tp->tp_vars, &tp->tp_winvar, VAR_SCOPE);
-#endif
-       tp->tp_ch_used = p_ch;
-    }
+    tp->tp_ch_used = p_ch;
+
     return tp;
 }
 
@@ -3491,7 +3501,9 @@ free_tabpage(tp)
     for (idx = 0; idx < SNAP_COUNT; ++idx)
        clear_snapshot(tp, idx);
 #ifdef FEAT_EVAL
-    vars_clear(&tp->tp_vars.dv_hashtab);       /* free all t: variables */
+    vars_clear(&tp->tp_vars->dv_hashtab);      /* free all t: variables */
+    hash_init(&tp->tp_vars->dv_hashtab);
+    unref_var_dict(tp->tp_vars);
 #endif
     vim_free(tp);
 }
@@ -4363,71 +4375,79 @@ win_alloc(after, hidden)
      * allocate window structure and linesizes arrays
      */
     new_wp = (win_T *)alloc_clear((unsigned)sizeof(win_T));
-    if (new_wp != NULL && win_alloc_lines(new_wp) == FAIL)
+    if (new_wp == NULL)
+       return NULL;
+
+    if (win_alloc_lines(new_wp) == FAIL)
     {
        vim_free(new_wp);
-       new_wp = NULL;
+       return NULL;
     }
 
-    if (new_wp != NULL)
+#ifdef FEAT_EVAL
+    /* init w: variables */
+    new_wp->w_vars = dict_alloc();
+    if (new_wp->w_vars == NULL)
     {
+       win_free_lsize(new_wp);
+       vim_free(new_wp);
+       return NULL;
+    }
+    init_var_dict(new_wp->w_vars, &new_wp->w_winvar, VAR_SCOPE);
+#endif
+
 #ifdef FEAT_AUTOCMD
-       /* Don't execute autocommands while the window is not properly
-        * initialized yet.  gui_create_scrollbar() may trigger a FocusGained
-        * event. */
-       block_autocmds();
+    /* Don't execute autocommands while the window is not properly
+     * initialized yet.  gui_create_scrollbar() may trigger a FocusGained
+     * event. */
+    block_autocmds();
 #endif
-       /*
-        * link the window in the window list
-        */
+    /*
+     * link the window in the window list
+     */
 #ifdef FEAT_WINDOWS
-       if (!hidden)
-           win_append(after, new_wp);
+    if (!hidden)
+       win_append(after, new_wp);
 #endif
 #ifdef FEAT_VERTSPLIT
-       new_wp->w_wincol = 0;
-       new_wp->w_width = Columns;
+    new_wp->w_wincol = 0;
+    new_wp->w_width = Columns;
 #endif
 
-       /* position the display and the cursor at the top of the file. */
-       new_wp->w_topline = 1;
+    /* position the display and the cursor at the top of the file. */
+    new_wp->w_topline = 1;
 #ifdef FEAT_DIFF
-       new_wp->w_topfill = 0;
+    new_wp->w_topfill = 0;
 #endif
-       new_wp->w_botline = 2;
-       new_wp->w_cursor.lnum = 1;
+    new_wp->w_botline = 2;
+    new_wp->w_cursor.lnum = 1;
 #ifdef FEAT_SCROLLBIND
-       new_wp->w_scbind_pos = 1;
+    new_wp->w_scbind_pos = 1;
 #endif
 
-       /* We won't calculate w_fraction until resizing the window */
-       new_wp->w_fraction = 0;
-       new_wp->w_prev_fraction_row = -1;
+    /* We won't calculate w_fraction until resizing the window */
+    new_wp->w_fraction = 0;
+    new_wp->w_prev_fraction_row = -1;
 
 #ifdef FEAT_GUI
-       if (gui.in_use)
-       {
-           gui_create_scrollbar(&new_wp->w_scrollbars[SBAR_LEFT],
-                   SBAR_LEFT, new_wp);
-           gui_create_scrollbar(&new_wp->w_scrollbars[SBAR_RIGHT],
-                   SBAR_RIGHT, new_wp);
-       }
-#endif
-#ifdef FEAT_EVAL
-       /* init w: variables */
-       init_var_dict(&new_wp->w_vars, &new_wp->w_winvar, VAR_SCOPE);
+    if (gui.in_use)
+    {
+       gui_create_scrollbar(&new_wp->w_scrollbars[SBAR_LEFT],
+               SBAR_LEFT, new_wp);
+       gui_create_scrollbar(&new_wp->w_scrollbars[SBAR_RIGHT],
+               SBAR_RIGHT, new_wp);
+    }
 #endif
 #ifdef FEAT_FOLDING
-       foldInitWin(new_wp);
+    foldInitWin(new_wp);
 #endif
 #ifdef FEAT_AUTOCMD
-       unblock_autocmds();
+    unblock_autocmds();
 #endif
 #ifdef FEAT_SEARCH_EXTRA
-       new_wp->w_match_head = NULL;
-       new_wp->w_next_match_id = 4;
+    new_wp->w_match_head = NULL;
+    new_wp->w_next_match_id = 4;
 #endif
-    }
     return new_wp;
 }
 
@@ -4488,7 +4508,9 @@ win_free(wp, tp)
     clear_winopt(&wp->w_allbuf_opt);
 
 #ifdef FEAT_EVAL
-    vars_clear(&wp->w_vars.dv_hashtab);            /* free all w: variables */
+    vars_clear(&wp->w_vars->dv_hashtab);       /* free all w: variables */
+    hash_init(&wp->w_vars->dv_hashtab);
+    unref_var_dict(wp->w_vars);
 #endif
 
     if (prevwin == wp)