]> granicus.if.org Git - vim/commitdiff
patch 8.0.1446: acessing freed memory after window command in auto command v8.0.1446
authorBram Moolenaar <Bram@vim.org>
Wed, 31 Jan 2018 18:06:50 +0000 (19:06 +0100)
committerBram Moolenaar <Bram@vim.org>
Wed, 31 Jan 2018 18:06:50 +0000 (19:06 +0100)
Problem:    Acessing freed memory after window command in auto command.
            (gy741)
Solution:   Adjust the pointer in the parent frame. (Christian Brabandt,
            closes #2467)

src/testdir/test_window_cmd.vim
src/version.c
src/window.c

index 925cfcc484cea72fff7cd160495160332b6270ab..69b139fe3b194e70b1e7a266014efda2e50b2250 100644 (file)
@@ -472,4 +472,15 @@ func Test_window_colon_command()
   exe "norm! v\<C-W>:\<C-U>echo v:version"
 endfunc
 
+func Test_access_freed_mem()
+  " This was accessing freed memory
+  au * 0 vs xxx
+  arg 0
+  argadd
+  all
+  all
+  au!
+  bwipe xxx
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
index dad27155590b05c773c5c77edd8819fff778df0d..e727c4a1bf3d01ba433cdbf97a588b3d8f1e653f 100644 (file)
@@ -771,6 +771,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1446,
 /**/
     1445,
 /**/
index a58fbbd7b7c4f24d93135c8e52522041d6258b2a..669f3bd6e856dee58b1f995323433f9aab30389d 100644 (file)
@@ -2731,6 +2731,8 @@ winframe_remove(
        if (frp2->fr_win != NULL)
            frp2->fr_win->w_frame = frp2->fr_parent;
        frp = frp2->fr_parent;
+       if (topframe->fr_child == frp2)
+           topframe->fr_child = frp;
        vim_free(frp2);
 
        frp2 = frp->fr_parent;
@@ -2754,6 +2756,8 @@ winframe_remove(
                    break;
                }
            }
+           if (topframe->fr_child == frp)
+               topframe->fr_child = frp2;
            vim_free(frp);
        }
     }
@@ -3499,7 +3503,6 @@ win_alloc_firstwin(win_T *oldwin)
     topframe = curwin->w_frame;
     topframe->fr_width = Columns;
     topframe->fr_height = Rows - p_ch;
-    topframe->fr_win = curwin;
 
     return OK;
 }
@@ -4812,7 +4815,12 @@ frame_remove(frame_T *frp)
     if (frp->fr_prev != NULL)
        frp->fr_prev->fr_next = frp->fr_next;
     else
+    {
        frp->fr_parent->fr_child = frp->fr_next;
+       /* special case: topframe->fr_child == frp */
+       if (topframe->fr_child == frp)
+           topframe->fr_child = frp->fr_next;
+    }
     if (frp->fr_next != NULL)
        frp->fr_next->fr_prev = frp->fr_prev;
 }