diff options
author | Po Lu <luangruo@yahoo.com> | 2022-08-27 09:54:16 +0800 |
---|---|---|
committer | Po Lu <luangruo@yahoo.com> | 2022-08-27 09:54:19 +0800 |
commit | 4015d561c39d29200bf1ac542844fd5f3ba99426 (patch) | |
tree | 9b57c8a8957040d42e41bd9355264dee8ec05f41 /src/xterm.c | |
parent | 6edff5ac331236f817032d6744a0855e5cc3d48d (diff) | |
download | emacs-4015d561c39d29200bf1ac542844fd5f3ba99426.tar.gz |
Fix crash when handling "swallowed" generic events
* src/xmenu.c (x_menu_translate_generic_event, x_menu_show):
Pass through more events, correctly.
* src/xterm.c (handle_one_xevent): Don't abort if must_free_data
and xi_event is NULL; this is an Xlib bug.
Diffstat (limited to 'src/xterm.c')
-rw-r--r-- | src/xterm.c | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/src/xterm.c b/src/xterm.c index b91d3a95173..c716d07adaf 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -20626,11 +20626,14 @@ handle_one_xevent (struct x_display_info *dpyinfo, bool must_free_data = false; XIEvent *xi_event = (XIEvent *) event->xcookie.data; + /* Sometimes the event is already claimed by GTK, which will free its data in due course. */ - if (!xi_event && XGetEventData (dpyinfo->display, &event->xcookie)) + if (!xi_event) { - must_free_data = true; + if (XGetEventData (dpyinfo->display, &event->xcookie)) + must_free_data = true; + xi_event = (XIEvent *) event->xcookie.data; } @@ -20638,7 +20641,25 @@ handle_one_xevent (struct x_display_info *dpyinfo, if (!xi_event) { - eassert (!must_free_data); + /* It may turn out that the event data has already been + implicitly freed for various reasons up to and + including XMenuActivate pushing some other event onto + the foreign-event queue, or x_menu_wait_for_events + calling XNextEvent through a timer that tries to wait + for input. + + In that case, XGetEventData will return True, but + cookie->data will be NULL. Since handling such input + events is not really important, we can afford to + discard them. + + The way Xlib is currently implemented makes calling + XFreeEventData unnecessary in this case, but call it + anyway, since not doing so may lead to a memory leak in + the future. */ + + if (must_free_data) + XFreeEventData (dpyinfo->display, &event->xcookie); goto OTHER; } |