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.
This commit is contained in:
Po Lu 2022-11-24 20:10:14 +08:00
parent 867e962cf5
commit 9fcff114b8

View file

@ -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 ();
}