diff options
author | Po Lu <luangruo@yahoo.com> | 2022-11-24 20:10:14 +0800 |
---|---|---|
committer | Po Lu <luangruo@yahoo.com> | 2022-11-24 20:10:32 +0800 |
commit | 9fcff114b8fe2d538699172fe756606441e67b92 (patch) | |
tree | d63b70006730686c73b44db2f5caf6566fb40dff /src/xterm.c | |
parent | 867e962cf5318399dfc17cc53c661db4bbd3c3d1 (diff) | |
download | emacs-9fcff114b8fe2d538699172fe756606441e67b92.tar.gz emacs-9fcff114b8fe2d538699172fe756606441e67b92.tar.bz2 emacs-9fcff114b8fe2d538699172fe756606441e67b92.zip |
Fix reentrancy problem/crash in xterm.c
* src/xterm.c (x_ignore_errors_for_next_request)
(x_stop_ignoring_errors): Be paranoid and block input inside the
protected section.
(x_focus_frame): Block input around critical section.
Diffstat (limited to 'src/xterm.c')
-rw-r--r-- | src/xterm.c | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/src/xterm.c b/src/xterm.c index cfd8c385d1d..7d855c92ccb 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -25461,6 +25461,17 @@ x_clean_failable_requests (struct x_display_info *dpyinfo) + (last - first)); } +/* Protect a section of X requests: ignore errors generated by X + requests made from now until `x_stop_ignoring_errors'. Each call + must be paired with a call to `x_stop_ignoring_errors', and + recursive calls inside the protected section are not allowed. + + The advantage over x_catch_errors followed by + x_uncatch_errors_after_check is that this function does not sync to + catch errors if requests were made. It should be used instead of + those two functions for catching errors around requests that do not + require a reply. */ + void x_ignore_errors_for_next_request (struct x_display_info *dpyinfo) { @@ -25468,7 +25479,13 @@ x_ignore_errors_for_next_request (struct x_display_info *dpyinfo) unsigned long next_request; #ifdef HAVE_GTK3 GdkDisplay *gdpy; +#endif + /* This code is not reentrant, so be sure nothing calls it + recursively in response to input. */ + block_input (); + +#ifdef HAVE_GTK3 /* GTK 3 tends to override our own error handler inside certain callbacks, which this can be called from. Instead of trying to restore our own, add a trap for the following requests with @@ -25537,6 +25554,8 @@ x_stop_ignoring_errors (struct x_display_info *dpyinfo) if (gdpy) gdk_x11_display_error_trap_pop_ignored (gdpy); #endif + + unblock_input (); } /* Undo the last x_catch_errors call. @@ -27836,6 +27855,10 @@ x_focus_frame (struct frame *f, bool noactivate) struct x_display_info *dpyinfo; Time time; + /* The code below is not reentrant wrt to dpyinfo->x_focus_frame and + friends being set. */ + block_input (); + dpyinfo = FRAME_DISPLAY_INFO (f); if (FRAME_X_EMBEDDED_P (f)) @@ -27866,7 +27889,7 @@ x_focus_frame (struct frame *f, bool noactivate) the current workspace, and mapping it, etc, before moving input focus to the frame. */ x_ewmh_activate_frame (f); - return; + goto out; } if (NILP (Vx_no_window_manager)) @@ -27900,6 +27923,9 @@ x_focus_frame (struct frame *f, bool noactivate) matter. */ CurrentTime); } + + out: + unblock_input (); } |