Avoid crashes upon C-g in nested invocations of 'read_char'
* src/keyboard.c (read_char, read_event_from_main_queue): Ensure the global value of getcjmp is restored when the stack is unwound by the likes of 'throw', by calling record_unwind_protect_ptr instead of restoring the value manually. (Bug#34394) (restore_getcjmp): Argument is now 'void *', to match the signature of record_unwind_protect_ptr.
This commit is contained in:
parent
ae4bfd52de
commit
10527fca66
1 changed files with 11 additions and 5 deletions
|
@ -360,7 +360,7 @@ static Lisp_Object make_lispy_focus_in (Lisp_Object);
|
|||
static Lisp_Object make_lispy_focus_out (Lisp_Object);
|
||||
static bool help_char_p (Lisp_Object);
|
||||
static void save_getcjmp (sys_jmp_buf);
|
||||
static void restore_getcjmp (sys_jmp_buf);
|
||||
static void restore_getcjmp (void *);
|
||||
static Lisp_Object apply_modifiers (int, Lisp_Object);
|
||||
static void restore_kboard_configuration (int);
|
||||
static void handle_interrupt (bool);
|
||||
|
@ -2126,12 +2126,14 @@ read_event_from_main_queue (struct timespec *end_time,
|
|||
return c;
|
||||
|
||||
/* Actually read a character, waiting if necessary. */
|
||||
ptrdiff_t count = SPECPDL_INDEX ();
|
||||
save_getcjmp (save_jump);
|
||||
record_unwind_protect_ptr (restore_getcjmp, save_jump);
|
||||
restore_getcjmp (local_getcjmp);
|
||||
if (!end_time)
|
||||
timer_start_idle ();
|
||||
c = kbd_buffer_get_event (&kb, used_mouse_menu, end_time);
|
||||
restore_getcjmp (save_jump);
|
||||
unbind_to (count, Qnil);
|
||||
|
||||
if (! NILP (c) && (kb != current_kboard))
|
||||
{
|
||||
|
@ -2620,10 +2622,12 @@ read_char (int commandflag, Lisp_Object map,
|
|||
{
|
||||
Lisp_Object tem0;
|
||||
|
||||
ptrdiff_t count = SPECPDL_INDEX ();
|
||||
save_getcjmp (save_jump);
|
||||
record_unwind_protect_ptr (restore_getcjmp, save_jump);
|
||||
restore_getcjmp (local_getcjmp);
|
||||
tem0 = sit_for (Vecho_keystrokes, 1, 1);
|
||||
restore_getcjmp (save_jump);
|
||||
unbind_to (count, Qnil);
|
||||
if (EQ (tem0, Qt)
|
||||
&& ! CONSP (Vunread_command_events))
|
||||
echo_now ();
|
||||
|
@ -2694,10 +2698,12 @@ read_char (int commandflag, Lisp_Object map,
|
|||
|
||||
timeout = min (timeout, MOST_POSITIVE_FIXNUM / delay_level * 4);
|
||||
timeout = delay_level * timeout / 4;
|
||||
ptrdiff_t count1 = SPECPDL_INDEX ();
|
||||
save_getcjmp (save_jump);
|
||||
record_unwind_protect_ptr (restore_getcjmp, save_jump);
|
||||
restore_getcjmp (local_getcjmp);
|
||||
tem0 = sit_for (make_fixnum (timeout), 1, 1);
|
||||
restore_getcjmp (save_jump);
|
||||
unbind_to (count1, Qnil);
|
||||
|
||||
if (EQ (tem0, Qt)
|
||||
&& ! CONSP (Vunread_command_events))
|
||||
|
@ -3320,7 +3326,7 @@ save_getcjmp (sys_jmp_buf temp)
|
|||
}
|
||||
|
||||
static void
|
||||
restore_getcjmp (sys_jmp_buf temp)
|
||||
restore_getcjmp (void *temp)
|
||||
{
|
||||
memcpy (getcjmp, temp, sizeof getcjmp);
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue