Mercurial > vim
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 |