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 <cb@256bit.org>
diff --git a/src/testdir/crash/nullpointer b/src/testdir/crash/nullpointer
new file mode 100644
index 0000000..c8ff3a4
--- /dev/null
+++ b/src/testdir/crash/nullpointer
Binary files differ
diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim
index 26590ab..5a91351 100644
--- a/src/testdir/test_autocmd.vim
+++ b/src/testdir/test_autocmd.vim
@@ -14,6 +14,13 @@
   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 @@
 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 @@
 
   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 @@
   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 @@
 	\ 'WinNewPre', 'WinLeave', 'WinNew', 'WinEnter'
 	\ ], g:record)
 
-  augroup testing
-    au!
-  augroup END
   unlet g:record
 endfunc
 
@@ -330,17 +335,15 @@
     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 @@
     let g:caught += 1
   endtry
   call assert_equal(4, g:caught)
-  augroup testing
-    au!
-  augroup END
   unlet g:caught
 endfunc
 
@@ -2807,7 +2807,8 @@
 
 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 @@
   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 @@
   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 9aef245..800f3e5 100644
--- a/src/testdir/test_crash.vim
+++ b/src/testdir/test_crash.vim
@@ -202,6 +202,12 @@
   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!