To: vim_dev@googlegroups.com Subject: Patch 9.0.0682 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 9.0.0682 Problem: Crash when popup with deleted timer is closed. (Igbanam Ogbuluijah) Solution: Check the timer still exists. (closes #11301) Files: src/window.c, src/time.c, src/proto/time.pro, src/testdir/test_timers.vim *** ../vim-9.0.0681/src/window.c 2022-10-06 11:38:48.154906022 +0100 --- src/window.c 2022-10-07 11:14:48.478345948 +0100 *************** *** 5322,5328 **** close_buffer(win, win->w_buffer, 0, FALSE, FALSE); } # if defined(FEAT_TIMERS) ! if (win->w_popup_timer != NULL) stop_timer(win->w_popup_timer); # endif vim_free(win->w_frame); --- 5322,5329 ---- close_buffer(win, win->w_buffer, 0, FALSE, FALSE); } # if defined(FEAT_TIMERS) ! // the timer may have been cleared, making the pointer invalid ! if (timer_valid(win->w_popup_timer)) stop_timer(win->w_popup_timer); # endif vim_free(win->w_frame); *** ../vim-9.0.0681/src/time.c 2022-09-17 21:07:52.099993159 +0100 --- src/time.c 2022-10-07 11:17:50.974349693 +0100 *************** *** 777,791 **** return abort; } # if defined(EXITFREE) || defined(PROTO) void timer_free_all() { - timer_T *timer; - while (first_timer != NULL) { ! timer = first_timer; remove_timer(timer); free_timer(timer); } --- 777,803 ---- return abort; } + /* + * Return TRUE if "timer" exists in the list of timers. + */ + int + timer_valid(timer_T *timer) + { + if (timer == NULL) + return FALSE; + for (timer_T *t = first_timer; t != NULL; t = t->tr_next) + if (t == timer) + return TRUE; + return FALSE; + } + # if defined(EXITFREE) || defined(PROTO) void timer_free_all() { while (first_timer != NULL) { ! timer_T *timer = first_timer; remove_timer(timer); free_timer(timer); } *** ../vim-9.0.0681/src/proto/time.pro 2022-08-27 21:29:28.257402847 +0100 --- src/proto/time.pro 2022-10-07 11:17:56.342349800 +0100 *************** *** 13,18 **** --- 13,19 ---- long check_due_timer(void); void stop_timer(timer_T *timer); int set_ref_in_timer(int copyID); + int timer_valid(timer_T *timer); void timer_free_all(void); void f_timer_info(typval_T *argvars, typval_T *rettv); void f_timer_pause(typval_T *argvars, typval_T *rettv); *** ../vim-9.0.0681/src/testdir/test_timers.vim 2022-09-24 17:44:18.962404471 +0100 --- src/testdir/test_timers.vim 2022-10-07 10:58:58.422313668 +0100 *************** *** 137,142 **** --- 137,156 ---- call assert_equal(0, len(info)) endfunc + def Test_timer_stopall_with_popup() + # Create a popup that times out after ten seconds. + # Another timer will fire in half a second and close it early after stopping + # all timers. + var pop = popup_create('Popup', {time: 10000}) + var tmr = timer_start(500, (_) => { + timer_stopall() + popup_clear() + }) + sleep 1 + assert_equal([], timer_info(tmr)) + assert_equal([], popup_list()) + enddef + func Test_timer_paused() let g:test_is_flaky = 1 let g:val = 0 *** ../vim-9.0.0681/src/version.c 2022-10-06 21:24:30.537632966 +0100 --- src/version.c 2022-10-07 11:15:21.842346650 +0100 *************** *** 701,702 **** --- 701,704 ---- { /* Add new patch number below this line */ + /**/ + 682, /**/ -- The psychic said, "God bless you." I said, "I didn't sneeze." She looked deep into my eyes and said, "You will, eventually." And, damn if she wasn't right. Two days later, I sneezed. --Ellen Degeneres /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///