On So, 25 Jun 2017, Bram Moolenaar wrote:
>
> Patch 8.0.0678
> Problem: When 'equalalways' is set and closing a window in a separate
> frame, not all window sizes are adjusted. (Glacambre)
> Solution: Resize all windows if the new current window is not in the same
> frame as the closed window. (closes #1707)
> Files: src/window.c, src/testdir/test_window_cmd.vim
> if (p_ea && (*p_ead == 'b' || *p_ead == dir))
> ! /* If the frame of the closed window contains the new current window,
> ! * only resize that frame. Otherwise resize all windows. */
> ! win_equal(curwin,
> ! curwin->w_frame->fr_parent == win_frame->fr_parent, dir);
This cannot be completely correct. win_frame->fr_parent is already freed
at window.c:2424 at win_free_mem(), so here we are accessing freed
memory and I think this is the reason for the build failures at travis
and appveyor.
How about the attached patch, which delays freeing the framepointer in
case of 'equalalways'?
Best,
Christian
--
Lieber an der Spitze stehen, als auf die Spitze treiben.
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.
diff --git a/src/window.c b/src/window.c
index 8078e011d..e9b601529 100644
--- a/src/window.c
+++ b/src/window.c
@@ -23,7 +23,7 @@ static void win_totop(int size, int flags);
static void win_equal_rec(win_T *next_curwin, int current, frame_T *topfr, int dir, int col, int row, int width, int height);
static int last_window(void);
static int close_last_window_tabpage(win_T *win, int free_buf, tabpage_T *prev_curtab);
-static win_T *win_free_mem(win_T *win, int *dirp, tabpage_T *tp);
+static win_T *win_free_mem(win_T *win, int *dirp, tabpage_T *tp, int ea);
static frame_T *win_altframe(win_T *win, tabpage_T *tp);
static tabpage_T *alt_tabpage(void);
static win_T *frame2win(frame_T *frp);
@@ -2283,6 +2283,7 @@ win_close(win_T *win, int free_buf)
int help_window = FALSE;
tabpage_T *prev_curtab = curtab;
frame_T *win_frame = win->w_frame;
+ int equalalways;
if (last_window())
{
@@ -2421,7 +2422,8 @@ win_close(win_T *win, int free_buf)
/* Free the memory used for the window and get the window that received
* the screen space. */
- wp = win_free_mem(win, &dir, NULL);
+ equalalways = p_ea && (*p_ead == 'b' || *p_ead == dir);
+ wp = win_free_mem(win, &dir, NULL, equalalways);
/* Make sure curwin isn't invalid. It can cause severe trouble when
* printing an error message. For win_equal() curbuf needs to be valid
@@ -2459,11 +2461,15 @@ win_close(win_T *win, int free_buf)
* using the window. */
check_cursor();
}
- if (p_ea && (*p_ead == 'b' || *p_ead == dir))
+ if (equalalways)
+ {
/* If the frame of the closed window contains the new current window,
* only resize that frame. Otherwise resize all windows. */
win_equal(curwin,
curwin->w_frame->fr_parent == win_frame->fr_parent, dir);
+ /* can be freed now */
+ vim_free(win_frame);
+ }
else
win_comp_pos();
if (close_curwin)
@@ -2558,7 +2564,7 @@ win_close_othertab(win_T *win, int free_buf, tabpage_T *tp)
}
/* Free the memory used for the window. */
- win_free_mem(win, &dir, tp);
+ win_free_mem(win, &dir, tp, FALSE);
if (free_tp)
free_tabpage(tp);
@@ -2572,7 +2578,8 @@ win_close_othertab(win_T *win, int free_buf, tabpage_T *tp)
win_free_mem(
win_T *win,
int *dirp, /* set to 'v' or 'h' for direction if 'ea' */
- tabpage_T *tp) /* tab page "win" is in, NULL for current */
+ tabpage_T *tp, /* tab page "win" is in, NULL for current */
+ int dont_free) /* if TRUE, then do not free the frame pointer yet */
{
frame_T *frp;
win_T *wp;
@@ -2580,7 +2587,8 @@ win_free_mem(
/* Remove the window and its frame from the tree of frames. */
frp = win->w_frame;
wp = winframe_remove(win, dirp, tp);
- vim_free(frp);
+ if (!dont_free)
+ vim_free(frp);
win_free(win, tp);
/* When deleting the current window of another tab page select a new
@@ -2605,13 +2613,13 @@ win_free_all(void)
# ifdef FEAT_AUTOCMD
if (aucmd_win != NULL)
{
- (void)win_free_mem(aucmd_win, &dummy, NULL);
+ (void)win_free_mem(aucmd_win, &dummy, NULL, FALSE);
aucmd_win = NULL;
}
# endif
while (firstwin != NULL)
- (void)win_free_mem(firstwin, &dummy, NULL);
+ (void)win_free_mem(firstwin, &dummy, NULL, FALSE);
/* No window should be used after this. Set curwin to NULL to crash
* instead of using freed memory. */