From 9fcff114b8fe2d538699172fe756606441e67b92 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Thu, 24 Nov 2022 20:10:14 +0800 Subject: [PATCH] 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. --- src/xterm.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) 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 (); } -- 2.39.2