Problem:  crash with WinNewPre autocommand

Commit: 
https://github.com/vim/vim/commit/fb3f9699362f8d51c3b48fcaea1eb2ed16c81454
Author: Christian Brabandt <c...@256bit.org>
Date:   Sun Aug 11 20:09:17 2024 +0200

    Problem:  crash with WinNewPre autocommand
    
    Problem:  crash with WinNewPre autocommand, because window
              structures are not yet safe to use
    Solution: Don't trigger WinNewPre on :tabnew
    
    Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt
index 0461c0454..f6d32db39 100644
--- a/runtime/doc/autocmd.txt
+++ b/runtime/doc/autocmd.txt
@@ -1,4 +1,4 @@
-*autocmd.txt*   For Vim version 9.1.  Last change: 2024 Jul 17
+*autocmd.txt*   For Vim version 9.1.  Last change: 2024 Aug 10
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -1427,8 +1427,10 @@ WinLeave                 Before leaving a window.  If 
the window to be
                                                        *WinNewPre*
 WinNewPre                      Before creating a new window. Triggered
                                before commands that modify window layout by
-                               creating a split or new tab page. Not done for
-                               the first window, when Vim has just started.
+                               creating a split.
+                               Not done for creating tabs or for the first
+                               window, as the window structure is not
+                               initialized yet and so is generally not safe.
                                It is not allowed to modify window layout
                                while executing commands for the WinNewPre
                                event.
diff --git a/src/testdir/crash/nullpointer b/src/testdir/crash/nullpointer
new file mode 100644
index 
0000000000000000000000000000000000000000..c8ff3a4832f3c9ff253315c61e9b9bf997c11038
GIT binary patch
literal 315
zcmZ3;Ra9g(nJYCeEu~e*FjbrZ2pnU$?Cov2bhuLaxk?Ng>N88*Wf@fR@{4k%Z3S4>
zV-4-??UT54z#@_=Dk_Cmg@uJyK#*8kq5uROJP=YqKtKnGLBOdrEhsfHg;R@DK>%cs
zqz#%jcAz$hQUONZ{L%tn1CXU37`T!QxqyI?Aum5UCpB@h3W%2<7gKGhV+aHWwVg3Q
z5C_CED*qFcQn^YJlQ>g~{&5N#E#xY)ss*Zk#mU8`2-3z~5A+<DXh{axmq0(FdBYOw
d4Uku?tR`|5rKV@*LpWubxt4|yCXj^q695*hO)3BY

literal 0
HcmV?d00001

diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim
index 26590ab33..5a913514b 100644
--- a/src/testdir/test_autocmd.vim
+++ b/src/testdir/test_autocmd.vim
@@ -14,6 +14,13 @@ func s:cleanup_buffers() abort
   endfor
 endfunc
 
+func CleanUpTestAuGroup()
+  augroup testing
+    au!
+  augroup END
+  augroup! testing
+endfunc
+
 func Test_vim_did_enter()
   call assert_false(v:vim_did_enter)
 
@@ -269,6 +276,7 @@ endfunc
 func Test_win_tab_autocmd()
   let g:record = []
 
+  defer CleanUpTestAuGroup()
   augroup testing
     au WinNewPre * call add(g:record, 'WinNewPre')
     au WinNew * call add(g:record, 'WinNew')
@@ -288,7 +296,7 @@ func Test_win_tab_autocmd()
 
   call assert_equal([
        \ 'WinNewPre', 'WinLeave', 'WinNew', 'WinEnter',
-       \ 'WinLeave', 'TabLeave', 'WinNewPre', 'WinNew', 'WinEnter', 'TabNew', 
'TabEnter',
+       \ 'WinLeave', 'TabLeave', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter',
        \ 'WinLeave', 'TabLeave', 'WinClosed', 'TabClosed', 'WinEnter', 
'TabEnter',
        \ 'WinLeave', 'WinClosed', 'WinEnter'
        \ ], g:record)
@@ -299,7 +307,7 @@ func Test_win_tab_autocmd()
   bwipe somefile
 
   call assert_equal([
-       \ 'WinLeave', 'TabLeave', 'WinNewPre', 'WinNew', 'WinEnter', 'TabNew', 
'TabEnter',
+       \ 'WinLeave', 'TabLeave', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter',
        \ 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter',
        \ 'WinClosed', 'TabClosed'
        \ ], g:record)
@@ -316,9 +324,6 @@ func Test_win_tab_autocmd()
        \ 'WinNewPre', 'WinLeave', 'WinNew', 'WinEnter'
        \ ], g:record)
 
-  augroup testing
-    au!
-  augroup END
   unlet g:record
 endfunc
 
@@ -330,17 +335,15 @@ func Test_WinNewPre()
     au WinNewPre * call add(g:layouts_pre, winlayout())
     au WinNew * call add(g:layouts_post, winlayout())
   augroup END
+  defer CleanUpTestAuGroup()
   split
   call assert_notequal(g:layouts_pre[0], g:layouts_post[0])
   split
   call assert_equal(g:layouts_pre[1], g:layouts_post[0])
   call assert_notequal(g:layouts_pre[1], g:layouts_post[1])
+  " not triggered for tabnew
   tabnew
-  call assert_notequal(g:layouts_pre[2], g:layouts_post[1])
-  call assert_notequal(g:layouts_pre[2], g:layouts_post[2])
-  augroup testing
-    au!
-  augroup END
+  call assert_equal(2, len(g:layouts_pre))
   unlet g:layouts_pre
   unlet g:layouts_post
 
@@ -383,9 +386,6 @@ func Test_WinNewPre()
     let g:caught += 1
   endtry
   call assert_equal(4, g:caught)
-  augroup testing
-    au!
-  augroup END
   unlet g:caught
 endfunc
 
@@ -2807,7 +2807,8 @@ endfunc
 
 func Test_autocmd_nested()
   let g:did_nested = 0
-  augroup Testing
+  defer CleanUpTestAuGroup()
+  augroup testing
     au WinNew * edit somefile
     au BufNew * let g:did_nested = 1
   augroup END
@@ -2817,7 +2818,7 @@ func Test_autocmd_nested()
   bwipe! somefile
 
   " old nested argument still works
-  augroup Testing
+  augroup testing
     au!
     au WinNew * nested edit somefile
     au BufNew * let g:did_nested = 1
@@ -4831,4 +4832,36 @@ func Test_KeyInputPre()
   au! KeyInputPre
 endfunc
 
+" those commands caused null pointer access, see #15464
+func Test_WinNewPre_crash()
+  defer CleanUpTestAuGroup()
+  let _cmdheight=&cmdheight
+  augroup testing
+    au!
+    autocmd WinNewPre * redraw
+  augroup END
+  tabnew
+  tabclose
+  augroup testing
+    au!
+    autocmd WinNewPre * wincmd t
+  augroup END
+  tabnew
+  tabclose
+  augroup testing
+    au!
+    autocmd WinNewPre * wincmd b
+  augroup END
+  tabnew
+  tabclose
+  augroup testing
+    au!
+    autocmd WinNewPre * set cmdheight+=1
+  augroup END
+  tabnew
+  tabclose
+  let &cmdheight=_cmdheight
+endfunc
+
+
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/testdir/test_crash.vim b/src/testdir/test_crash.vim
index 9aef24502..800f3e5e6 100644
--- a/src/testdir/test_crash.vim
+++ b/src/testdir/test_crash.vim
@@ -202,6 +202,12 @@ func Test_crash1_3()
   call term_sendkeys(buf, args)
   call TermWait(buf, 150)
 
+  let file = 'crash/nullpointer'
+  let cmn_args = "%s -u NONE -i NONE -n -e -s -S %s -c ':qa!'\<cr>"
+  let args = printf(cmn_args, vim, file)
+  call term_sendkeys(buf, args)
+  call TermWait(buf, 50)
+
   " clean up
   exe buf .. "bw!"
   bw!
diff --git a/src/version.c b/src/version.c
index 03658333a..ef1ffb0ae 100644
--- a/src/version.c
+++ b/src/version.c
@@ -704,6 +704,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    671,
 /**/
     670,
 /**/
diff --git a/src/window.c b/src/window.c
index 70c72bca7..43a15e056 100644
--- a/src/window.c
+++ b/src/window.c
@@ -4607,6 +4607,11 @@ free_tabpage(tabpage_T *tp)
  * It will edit the current buffer, like after ":split".
  * When "after" is 0 put it just after the current Tab page.
  * Otherwise put it just before tab page "after".
+ *
+ * Does not trigger WinNewPre, since the window structures
+ * are not completly setup yet and could cause dereferencing
+ * NULL pointers
+ *
  * Return FAIL or OK.
  */
     int
@@ -4640,8 +4645,6 @@ win_new_tabpage(int after)
     newtp->tp_localdir = (tp->tp_localdir == NULL)
                                    ? NULL : vim_strsave(tp->tp_localdir);
 
-    trigger_winnewpre();
-
     // Create a new empty window.
     if (win_alloc_firstwin(tp->tp_curwin) == OK)
     {

-- 
-- 
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 vim_dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/E1sdD5t-00CWwA-SY%40256bit.org.

Raspunde prin e-mail lui