From 6a19ab9cceea774b0dc74eab8932167307d1e925 Mon Sep 17 00:00:00 2001 From: Pip Cet Date: Tue, 21 Apr 2026 13:08:36 +0000 Subject: [PATCH] Don't modify kbd_fetch_ptr in x_delete_selection_requests (bug#80863) This code may be called from within the loop in process_special_events which assumed kbd_fetch_ptr remains unchanged. This caused a buffer underflow which resulted in the entire kbd buffer being replayed. * src/xterm.c (x_delete_selection_requests): Simply clear deleted events rather than rotating the kbd buffer. --- src/xterm.c | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/src/xterm.c b/src/xterm.c index b02380a7171..4de0b24081f 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -31784,7 +31784,6 @@ static void x_delete_selection_requests (struct x_display_info *dpyinfo) { union buffered_input_event *event; - int moved_events; for (event = kbd_fetch_ptr; event != kbd_store_ptr; event = X_NEXT_KBD_EVENT (event)) @@ -31795,25 +31794,8 @@ x_delete_selection_requests (struct x_display_info *dpyinfo) if (SELECTION_EVENT_DPYINFO (&event->sie) != dpyinfo) continue; - /* Remove the event from the fifo buffer before processing; - otherwise swallow_events called recursively could see it - and process it again. To do this, we move the events - between kbd_fetch_ptr and EVENT one slot to the right, - cyclically. */ - - if (event < kbd_fetch_ptr) - { - memmove (kbd_buffer + 1, kbd_buffer, - (event - kbd_buffer) * sizeof *kbd_buffer); - kbd_buffer[0] = kbd_buffer[KBD_BUFFER_SIZE - 1]; - moved_events = kbd_buffer + KBD_BUFFER_SIZE - 1 - kbd_fetch_ptr; - } - else - moved_events = event - kbd_fetch_ptr; - - memmove (kbd_fetch_ptr + 1, kbd_fetch_ptr, - moved_events * sizeof *kbd_fetch_ptr); - kbd_fetch_ptr = X_NEXT_KBD_EVENT (kbd_fetch_ptr); + EVENT_INIT (event->ie); + event->ie.kind = NO_EVENT; /* `detect_input_pending' will then recompute whether or not pending input events exist. */