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 -- Br...@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 ///