diff src/window.c @ 4287:dc3efb6d5a08 v7.3.893

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)
author Bram Moolenaar <bram@vim.org>
date Mon, 15 Apr 2013 12:27:36 +0200
parents 48b54c590dc8
children b01e3cff9253
line wrap: on
line diff
--- a/src/window.c
+++ b/src/window.c
@@ -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)
+    {
+	vim_free(tp);
+	return NULL;
+    }
+    init_var_dict(tp->tp_vars, &tp->tp_winvar, VAR_SCOPE);
+# endif
+
 # ifdef FEAT_GUI
-	int	i;
-
-	for (i = 0; i < 3; i++)
-	    tp->tp_prev_which_scrollbars[i] = -1;
+    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;
-    }
-
-    if (new_wp != NULL)
-    {
+	return 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();
-#endif
-	/*
-	 * link the window in the window list
-	 */
+    /* 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;
-#endif
-
-	/* position the display and the cursor at the top of the file. */
-	new_wp->w_topline = 1;
+    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;
 #ifdef FEAT_DIFF
-	new_wp->w_topfill = 0;
-#endif
-	new_wp->w_botline = 2;
-	new_wp->w_cursor.lnum = 1;
+    new_wp->w_topfill = 0;
+#endif
+    new_wp->w_botline = 2;
+    new_wp->w_cursor.lnum = 1;
 #ifdef FEAT_SCROLLBIND
-	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;
+    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;
 
 #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;
-#endif
-    }
+    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)