updated for version 7.3.893
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)
diff --git a/src/window.c b/src/window.c
index 1a09c91..fadbb92 100644
--- a/src/window.c
+++ b/src/window.c
@@ -3457,25 +3457,35 @@
alloc_tabpage()
{
tabpage_T *tp;
+# ifdef FEAT_GUI
+ int i;
+# endif
+
tp = (tabpage_T *)alloc_clear((unsigned)sizeof(tabpage_T));
- if (tp != NULL)
- {
-# ifdef FEAT_GUI
- int i;
+ if (tp == NULL)
+ return NULL;
- for (i = 0; i < 3; i++)
- tp->tp_prev_which_scrollbars[i] = -1;
+# ifdef FEAT_EVAL
+ /* init t: variables */
+ tp->tp_vars = dict_alloc();
+ if (tp->tp_vars == NULL)
+ {
+ vim_free(tp);
+ return NULL;
+ }
+ init_var_dict(tp->tp_vars, &tp->tp_winvar, VAR_SCOPE);
+# endif
+
+# 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 @@
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 @@
* 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)
{
-#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();
+ 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
- /*
- * link the window in the window list
- */
+
+#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();
+#endif
+ /*
+ * 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 @@
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)