patch 9.1.1773: Crash in BufLeave after BufUnload closes other windows
Problem:  Crash in BufLeave/WinLeave/TabLeave when closing window after
          BufUnload closes all other windows in the tab page.
Solution: Avoid duplicate BufLeave/WinLeave events. Trigger TabLeave
          before removing the buffer (zeertzjq).
related: #14166
related: neovim/neovim#33603
closes: #18330
Signed-off-by: zeertzjq <zeertzjq@outlook.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
			
			
This commit is contained in:
		
				
					committed by
					
						 Christian Brabandt
						Christian Brabandt
					
				
			
			
				
	
			
			
			
						parent
						
							86e8e909f2
						
					
				
				
					commit
					0c70820015
				
			
							
								
								
									
										14
									
								
								src/window.c
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								src/window.c
									
									
									
									
									
								
							| @ -2605,10 +2605,12 @@ close_last_window_tabpage( | ||||
|      * page and then close the window and the tab page.  This avoids that | ||||
|      * curwin and curtab are invalid while we are freeing memory, they may | ||||
|      * be used in GUI events. | ||||
|      * Don't trigger autocommands yet, they may use wrong values, so do | ||||
|      * Don't trigger *Enter autocommands yet, they may use wrong values, so do | ||||
|      * that below. | ||||
|      * Do trigger *Leave autocommands, unless win->w_buffer is NULL, in which | ||||
|      * case they have already been triggered. | ||||
|      */ | ||||
|     goto_tabpage_tp(alt_tabpage(), FALSE, TRUE); | ||||
|     goto_tabpage_tp(alt_tabpage(), FALSE, win->w_buffer != NULL); | ||||
|  | ||||
|     // Safety check: Autocommands may have closed the window when jumping | ||||
|     // to the other tab page. | ||||
| @ -2906,6 +2908,7 @@ win_close(win_T *win, int free_buf) | ||||
| 	win_comp_pos(); | ||||
| 	win_fix_scroll(FALSE); | ||||
|     } | ||||
|  | ||||
|     if (close_curwin) | ||||
|     { | ||||
| 	// Pass WEE_ALLOW_PARSE_MESSAGES to decrement dont_parse_messages | ||||
| @ -2923,6 +2926,13 @@ win_close(win_T *win, int free_buf) | ||||
| 	    apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf); | ||||
|     } | ||||
|  | ||||
|     if (ONE_WINDOW && curwin->w_locked && curbuf->b_locked_split | ||||
| 	    && first_tabpage->tp_next != NULL) | ||||
| 	// The new curwin is the last window in the current tab page, and it is | ||||
| 	// already being closed.  Trigger TabLeave now, as after its buffer is | ||||
| 	// removed it's no longer safe to do that. | ||||
| 	apply_autocmds(EVENT_TABLEAVE, NULL, NULL, FALSE, curbuf); | ||||
|  | ||||
|     --split_disallowed; | ||||
| #ifdef MESSAGE_QUEUE | ||||
|     if (!did_decrement) | ||||
|  | ||||
		Reference in New Issue
	
	Block a user