From 0cbea4972ef0373507f3b49a775ef780a7f0f292 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sun, 26 May 2024 19:41:30 +0300 Subject: [PATCH] Prevent crashes due to redisplay while realizing the default face * src/xfaces.c (Finternal_merge_in_global_face) (realize_default_face): Prevent redisplay while the default face is being realized. (Bug#71176) (cherry picked from commit 74b8043e60dde6710d0ba413278c2cb36a84f8f2) --- src/xdisp.c | 6 ++++-- src/xfaces.c | 14 ++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/xdisp.c b/src/xdisp.c index 7a00b297d61..47675fcc80a 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -13377,8 +13377,10 @@ echo_area_display (bool update_frame_p) w = XWINDOW (mini_window); f = XFRAME (WINDOW_FRAME (w)); - /* Don't display if frame is invisible or not yet initialized. */ - if (!FRAME_REDISPLAY_P (f) || !f->glyphs_initialized_p) + /* Don't display if frame is invisible or not yet initialized or + if redisplay is inhibited. */ + if (!FRAME_REDISPLAY_P (f) || !f->glyphs_initialized_p + || !NILP (Vinhibit_redisplay)) return; #ifdef HAVE_WINDOW_SYSTEM diff --git a/src/xfaces.c b/src/xfaces.c index 5192b22ce0a..258fbc52e64 100644 --- a/src/xfaces.c +++ b/src/xfaces.c @@ -4246,6 +4246,12 @@ Default face attributes override any local face attributes. */) /* This can be NULL (e.g., in batch mode). */ if (oldface) { + /* In some cases, realize_face below can call Lisp, which could + trigger redisplay. But we are in the process of realizing + the default face, and therefore are not ready to do display. */ + specpdl_ref count = SPECPDL_INDEX (); + specbind (Qinhibit_redisplay, Qt); + /* Ensure that the face vector is fully specified by merging the previously-cached vector. */ memcpy (attrs, oldface->lface, sizeof attrs); @@ -4291,6 +4297,8 @@ Default face attributes override any local face attributes. */) gvec[LFACE_BACKGROUND_INDEX]); Fmodify_frame_parameters (frame, arg); } + + unbind_to (count, Qnil); } } @@ -5959,7 +5967,13 @@ realize_default_face (struct frame *f) eassert (lface_fully_specified_p (XVECTOR (lface)->contents)); check_lface (lface); memcpy (attrs, xvector_contents (lface), sizeof attrs); + /* In some cases, realize_face below can call Lisp, which could + trigger redisplay. But we are in the process of realizing + the default face, and therefore are not ready to do display. */ + specpdl_ref count = SPECPDL_INDEX (); + specbind (Qinhibit_redisplay, Qt); struct face *face = realize_face (c, attrs, DEFAULT_FACE_ID); + unbind_to (count, Qnil); #ifndef HAVE_WINDOW_SYSTEM (void) face; -- 2.39.5