Subject: Re: bug#76559: 31.0.50; [-O3 + PGTK] Crash when 'copying as kill'/'killing word'

From: Po Lu <[email-masked]>
Date: Thu, 27 Feb 2025 20:38:19 +0800

Pip Cet <[email-masked]> writes:

> See my other message.  I'm still puzzled as to why an unsafe cast in one
> call path modifies the assumptions made for another call path, but I
> guess it all falls under undefined behavior and we should simply apply
> that patch and make sure to follow the C standard more closely.

I revisited the material provisions in n1256, and the problem is that a
`union buffered_input_event' is read from the EVENT pointer, whether or
not the object behind the pointer is of a type compatible with the
union.  It is permissible for an object whose type is a member of a
union or aggregate to be accessed from a pointer whose type is the same
union or aggregate, but apparently not more generally to access a union
from a pointer of its type from which it is only defined to access one
of its members, even if the latter is identical in size.

I propose this patch:

diff --git a/src/keyboard.c b/src/keyboard.c
index b22814d702d..0c83880c491 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -3807,7 +3807,13 @@ kbd_buffer_store_buffered_event (union buffered_input_event *event,
   union buffered_input_event *next_slot = next_kbd_event (kbd_store_ptr);
   if (kbd_fetch_ptr != next_slot)
     {
-      *kbd_store_ptr = *event;
+#if defined HAVE_X11 || defined HAVE_PGTK
+      if (event->kind == SELECTION_REQUEST_EVENT
+	  || event->kind == SELECTION_CLEAR_EVENT)
+	kbd_store_ptr->sie = event->sie;
+      else
+	kbd_store_ptr->ie = event->ie;
+#endif /* HAVE_X11 || defined HAVE_PGTK */
       kbd_store_ptr = next_slot;
 #ifdef subprocesses
       if (kbd_buffer_nr_stored () > KBD_BUFFER_SIZE / 2

Please test.