From 27db0625e5348d50bc59674c0a8c8d45ed4db874 Mon Sep 17 00:00:00 2001 From: Tim Ruffing Date: Wed, 27 Dec 2023 14:32:09 +0100 Subject: [PATCH 3/4] Fix -1 leaking from C to lisp in 'read-event' etc. This fixes a bug that could make 'read-event', 'read-char', and 'read-char-exclusive' erroneously return -1, an internal magic return value of 'read_char' leaked from C to lisp. * src/keyboard.c (read_char, read_key_sequence): Move handling of the end of a keyboard macro from 'read_char' to its caller 'read_key_sequence', which is the only caller that can meaningfully deal with this case. --- src/keyboard.c | 39 +++++++++++++++------------------------ 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/src/keyboard.c b/src/keyboard.c index 041b616d9aa..9b5e020238c 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -2610,7 +2610,8 @@ read_char (int commandflag, Lisp_Object map, goto reread_for_input_method; } - if (!NILP (Vexecuting_kbd_macro)) + /* If we're executing a macro, process it unless we are at its end. */ + if (!NILP (Vexecuting_kbd_macro) && !at_end_of_macro_p ()) { /* We set this to Qmacro; since that's not a frame, nobody will try to switch frames on us, and the selected window will @@ -2624,15 +2625,6 @@ read_char (int commandflag, Lisp_Object map, selected. */ Vlast_event_frame = internal_last_event_frame = Qmacro; - /* Exit the macro if we are at the end. - Also, some things replace the macro with t - to force an early exit. */ - if (at_end_of_macro_p ()) - { - XSETINT (c, -1); - goto exit; - } - c = Faref (Vexecuting_kbd_macro, make_int (executing_kbd_macro_index)); if (STRINGP (Vexecuting_kbd_macro) && (XFIXNAT (c) & 0x80) && (XFIXNAT (c) <= 0xff)) @@ -10684,8 +10676,19 @@ read_key_sequence (Lisp_Object *keybuf, Lisp_Object prompt, } used_mouse_menu = used_mouse_menu_history[t]; } - - /* If not, we should actually read a character. */ + /* If we're at the end of a macro, exit it by returning 0, + unless there are unread events pending. */ + else if (!NILP (Vexecuting_kbd_macro) + && at_end_of_macro_p () + && !requeued_events_pending_p ()) + { + t = 0; + /* The Microsoft C compiler can't handle the goto that + would go here. */ + dummyflag = true; + break; + } + /* Otherwise, we should actually read a character. */ else { { @@ -10777,18 +10780,6 @@ read_key_sequence (Lisp_Object *keybuf, Lisp_Object prompt, return -1; } - /* read_char returns -1 at the end of a macro. - Emacs 18 handles this by returning immediately with a - zero, so that's what we'll do. */ - if (FIXNUMP (key) && XFIXNUM (key) == -1) - { - t = 0; - /* The Microsoft C compiler can't handle the goto that - would go here. */ - dummyflag = true; - break; - } - /* If the current buffer has been changed from under us, the keymap may have changed, so replay the sequence. */ if (BUFFERP (key)) -- 2.43.0