emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master 1431f66: Avoid crashes when redisplayng a window ch


From: Eli Zaretskii
Subject: [Emacs-diffs] master 1431f66: Avoid crashes when redisplayng a window changes faces or fonts
Date: Sat, 17 Oct 2015 12:12:26 +0000

branch: master
commit 1431f667504b610471257802aa2f2f4f0d8443de
Author: Eli Zaretskii <address@hidden>
Commit: Eli Zaretskii <address@hidden>

    Avoid crashes when redisplayng a window changes faces or fonts
    
    * src/xdisp.c (redisplay_internal): If redisplaying the selected
    window or one of the frames turns on the frame's 'redisplay' flag,
    redisplay again.  (Bug#21428)
    
    * src/frame.c (x_set_font): Set the frame's 'fonts_changed' flag.
---
 src/frame.c |    4 ++++
 src/xdisp.c |   21 +++++++++++++++++++--
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/src/frame.c b/src/frame.c
index 98a7a57..6d596a4 100644
--- a/src/frame.c
+++ b/src/frame.c
@@ -3651,6 +3651,10 @@ x_set_font (struct frame *f, Lisp_Object arg, 
Lisp_Object oldval)
   /* Attempt to hunt down bug#16028.  */
   SET_FRAME_GARBAGED (f);
 
+  /* This is important if we are called by some Lisp as part of
+     redisplaying the frame, see redisplay_internal.  */
+  f->fonts_changed = true;
+
   recompute_basic_faces (f);
 
   do_pending_window_change (0);
diff --git a/src/xdisp.c b/src/xdisp.c
index a793157..986e13f 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -13810,6 +13810,7 @@ redisplay_internal (void)
              bool gcscrollbars
                /* Only GC scrollbars when we redisplay the whole frame.  */
                = f->redisplay || !REDISPLAY_SOME_P ();
+             bool f_redisplay_flag = f->redisplay;
              /* Mark all the scroll bars to be removed; we'll redeem
                 the ones we want when we redisplay their windows.  */
              if (gcscrollbars && FRAME_TERMINAL (f)->condemn_scroll_bars_hook)
@@ -13853,6 +13854,20 @@ redisplay_internal (void)
                        goto retry_frame;
                    }
 
+                 /* If the frame's redisplay flag was not set before
+                    we went about redisplaying its windows, but it is
+                    set now, that means we employed some redisplay
+                    optimizations inside redisplay_windows, and
+                    bypassed producing some screen lines.  But if
+                    f->redisplay is now set, it might mean the old
+                    faces are no longer valid (e.g., if redisplaying
+                    some window called some Lisp which defined a new
+                    face or redefined an existing face), so trying to
+                    use them in update_frame will segfault.
+                    Therefore, we must redisplay this frame.  */
+                 if (!f_redisplay_flag && f->redisplay)
+                   goto retry_frame;
+
                  /* Prevent various kinds of signals during display
                     update.  stdio is not robust about handling
                     signals, which can cause an apparent I/O error.  */
@@ -13906,8 +13921,10 @@ redisplay_internal (void)
       /* Compare desired and current matrices, perform output.  */
 
     update:
-      /* If fonts changed, display again.  */
-      if (sf->fonts_changed)
+      /* If fonts changed, display again.  Likewise if redisplay_window_1
+        above caused some change (e.g., a change in faces) that requires
+        considering the entire frame again.  */
+      if (sf->fonts_changed || sf->redisplay)
        goto retry;
 
       /* Prevent freeing of realized faces, since desired matrices are



reply via email to

[Prev in Thread] Current Thread [Next in Thread]