comparison src/window.c @ 30429:69ff2bd737a9 v9.0.0550

patch 9.0.0550: crash when closing a tabpage and buffer is NULL Commit: https://github.com/vim/vim/commit/62de54b48d6354d4622ec0b21ffa4cf3cf312505 Author: zeertzjq <zeertzjq@outlook.com> Date: Thu Sep 22 18:08:37 2022 +0100 patch 9.0.0550: crash when closing a tabpage and buffer is NULL Problem: Crash when closing a tabpage and buffer is NULL. Solution: Adjust how autocommands are triggered when closing a window. (closes #11198, closes #11197)
author Bram Moolenaar <Bram@vim.org>
date Thu, 22 Sep 2022 19:15:03 +0200
parents b5f67135fcb6
children e3091fc473a1
comparison
equal deleted inserted replaced
30428:e57e07951f98 30429:69ff2bd737a9
2338 buf_T *buf, 2338 buf_T *buf,
2339 int keep_curwin) // don't close "curwin" 2339 int keep_curwin) // don't close "curwin"
2340 { 2340 {
2341 win_T *wp; 2341 win_T *wp;
2342 tabpage_T *tp, *nexttp; 2342 tabpage_T *tp, *nexttp;
2343 int h = tabline_height();
2344 int count = tabpage_index(NULL); 2343 int count = tabpage_index(NULL);
2345 2344
2346 ++RedrawingDisabled; 2345 ++RedrawingDisabled;
2347 2346
2348 for (wp = firstwin; wp != NULL && !ONE_WINDOW; ) 2347 for (wp = firstwin; wp != NULL && !ONE_WINDOW; )
2382 2381
2383 --RedrawingDisabled; 2382 --RedrawingDisabled;
2384 2383
2385 if (count != tabpage_index(NULL)) 2384 if (count != tabpage_index(NULL))
2386 apply_autocmds(EVENT_TABCLOSED, NULL, NULL, FALSE, curbuf); 2385 apply_autocmds(EVENT_TABCLOSED, NULL, NULL, FALSE, curbuf);
2387
2388 redraw_tabline = TRUE;
2389 if (h != tabline_height())
2390 shell_new_rows();
2391 } 2386 }
2392 2387
2393 /* 2388 /*
2394 * Return TRUE if the current window is the only window that exists (ignoring 2389 * Return TRUE if the current window is the only window that exists (ignoring
2395 * "aucmd_win"). 2390 * "aucmd_win").
2444 * be used in GUI events. 2439 * be used in GUI events.
2445 * Don't trigger autocommands yet, they may use wrong values, so do 2440 * Don't trigger autocommands yet, they may use wrong values, so do
2446 * that below. 2441 * that below.
2447 */ 2442 */
2448 goto_tabpage_tp(alt_tabpage(), FALSE, TRUE); 2443 goto_tabpage_tp(alt_tabpage(), FALSE, TRUE);
2449 redraw_tabline = TRUE;
2450 2444
2451 // Safety check: Autocommands may have closed the window when jumping 2445 // Safety check: Autocommands may have closed the window when jumping
2452 // to the other tab page. 2446 // to the other tab page.
2453 if (valid_tabpage(prev_curtab) && prev_curtab->tp_firstwin == win) 2447 if (valid_tabpage(prev_curtab) && prev_curtab->tp_firstwin == win)
2454 {
2455 int h = tabline_height();
2456
2457 win_close_othertab(win, free_buf, prev_curtab); 2448 win_close_othertab(win, free_buf, prev_curtab);
2458 if (h != tabline_height())
2459 shell_new_rows();
2460 }
2461 #ifdef FEAT_JOB_CHANNEL 2449 #ifdef FEAT_JOB_CHANNEL
2462 entering_window(curwin); 2450 entering_window(curwin);
2463 #endif 2451 #endif
2464 // Since goto_tabpage_tp above did not trigger *Enter autocommands, do 2452 // Since goto_tabpage_tp above did not trigger *Enter autocommands, do
2465 // that now. 2453 // that now.
2654 // Autocommands may have moved to another tab page. 2642 // Autocommands may have moved to another tab page.
2655 if (curtab != prev_curtab && win_valid_any_tab(win) 2643 if (curtab != prev_curtab && win_valid_any_tab(win)
2656 && win->w_buffer == NULL) 2644 && win->w_buffer == NULL)
2657 { 2645 {
2658 // Need to close the window anyway, since the buffer is NULL. 2646 // Need to close the window anyway, since the buffer is NULL.
2647 // Don't trigger autocmds with a NULL buffer.
2648 block_autocmds();
2659 win_close_othertab(win, FALSE, prev_curtab); 2649 win_close_othertab(win, FALSE, prev_curtab);
2650 unblock_autocmds();
2660 return FAIL; 2651 return FAIL;
2661 } 2652 }
2662 2653
2663 // Autocommands may have closed the window already or closed the only 2654 // Autocommands may have closed the window already or closed the only
2664 // other window. 2655 // other window.
2905 return; 2896 return;
2906 2897
2907 // When closing the last window in a tab page remove the tab page. 2898 // When closing the last window in a tab page remove the tab page.
2908 if (tp->tp_firstwin == tp->tp_lastwin) 2899 if (tp->tp_firstwin == tp->tp_lastwin)
2909 { 2900 {
2901 int h = tabline_height();
2902
2910 if (tp == first_tabpage) 2903 if (tp == first_tabpage)
2911 first_tabpage = tp->tp_next; 2904 first_tabpage = tp->tp_next;
2912 else 2905 else
2913 { 2906 {
2914 for (ptp = first_tabpage; ptp != NULL && ptp->tp_next != tp; 2907 for (ptp = first_tabpage; ptp != NULL && ptp->tp_next != tp;
2920 return; 2913 return;
2921 } 2914 }
2922 ptp->tp_next = tp->tp_next; 2915 ptp->tp_next = tp->tp_next;
2923 } 2916 }
2924 free_tp = TRUE; 2917 free_tp = TRUE;
2918 redraw_tabline = TRUE;
2919 if (h != tabline_height())
2920 shell_new_rows();
2925 } 2921 }
2926 2922
2927 // Free the memory used for the window. 2923 // Free the memory used for the window.
2928 win_free_mem(win, &dir, tp); 2924 win_free_mem(win, &dir, tp);
2929 2925