diff options
| author | Eli Zaretskii | 2015-10-17 15:10:58 +0300 |
|---|---|---|
| committer | Eli Zaretskii | 2015-10-17 15:10:58 +0300 |
| commit | 1431f667504b610471257802aa2f2f4f0d8443de (patch) | |
| tree | 45f69f553a2abfa83b8f366fcb648760dbd658e3 /src | |
| parent | 57be62f97b8442218f4fa6979cf27b36d5d5f540 (diff) | |
| download | emacs-1431f667504b610471257802aa2f2f4f0d8443de.tar.gz emacs-1431f667504b610471257802aa2f2f4f0d8443de.zip | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/frame.c | 4 | ||||
| -rw-r--r-- | src/xdisp.c | 21 |
2 files changed, 23 insertions, 2 deletions
diff --git a/src/frame.c b/src/frame.c index 98a7a57a988..6d596a48e23 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) | |||
| 3651 | /* Attempt to hunt down bug#16028. */ | 3651 | /* Attempt to hunt down bug#16028. */ |
| 3652 | SET_FRAME_GARBAGED (f); | 3652 | SET_FRAME_GARBAGED (f); |
| 3653 | 3653 | ||
| 3654 | /* This is important if we are called by some Lisp as part of | ||
| 3655 | redisplaying the frame, see redisplay_internal. */ | ||
| 3656 | f->fonts_changed = true; | ||
| 3657 | |||
| 3654 | recompute_basic_faces (f); | 3658 | recompute_basic_faces (f); |
| 3655 | 3659 | ||
| 3656 | do_pending_window_change (0); | 3660 | do_pending_window_change (0); |
diff --git a/src/xdisp.c b/src/xdisp.c index a793157f086..986e13f43b5 100644 --- a/src/xdisp.c +++ b/src/xdisp.c | |||
| @@ -13810,6 +13810,7 @@ redisplay_internal (void) | |||
| 13810 | bool gcscrollbars | 13810 | bool gcscrollbars |
| 13811 | /* Only GC scrollbars when we redisplay the whole frame. */ | 13811 | /* Only GC scrollbars when we redisplay the whole frame. */ |
| 13812 | = f->redisplay || !REDISPLAY_SOME_P (); | 13812 | = f->redisplay || !REDISPLAY_SOME_P (); |
| 13813 | bool f_redisplay_flag = f->redisplay; | ||
| 13813 | /* Mark all the scroll bars to be removed; we'll redeem | 13814 | /* Mark all the scroll bars to be removed; we'll redeem |
| 13814 | the ones we want when we redisplay their windows. */ | 13815 | the ones we want when we redisplay their windows. */ |
| 13815 | if (gcscrollbars && FRAME_TERMINAL (f)->condemn_scroll_bars_hook) | 13816 | if (gcscrollbars && FRAME_TERMINAL (f)->condemn_scroll_bars_hook) |
| @@ -13853,6 +13854,20 @@ redisplay_internal (void) | |||
| 13853 | goto retry_frame; | 13854 | goto retry_frame; |
| 13854 | } | 13855 | } |
| 13855 | 13856 | ||
| 13857 | /* If the frame's redisplay flag was not set before | ||
| 13858 | we went about redisplaying its windows, but it is | ||
| 13859 | set now, that means we employed some redisplay | ||
| 13860 | optimizations inside redisplay_windows, and | ||
| 13861 | bypassed producing some screen lines. But if | ||
| 13862 | f->redisplay is now set, it might mean the old | ||
| 13863 | faces are no longer valid (e.g., if redisplaying | ||
| 13864 | some window called some Lisp which defined a new | ||
| 13865 | face or redefined an existing face), so trying to | ||
| 13866 | use them in update_frame will segfault. | ||
| 13867 | Therefore, we must redisplay this frame. */ | ||
| 13868 | if (!f_redisplay_flag && f->redisplay) | ||
| 13869 | goto retry_frame; | ||
| 13870 | |||
| 13856 | /* Prevent various kinds of signals during display | 13871 | /* Prevent various kinds of signals during display |
| 13857 | update. stdio is not robust about handling | 13872 | update. stdio is not robust about handling |
| 13858 | signals, which can cause an apparent I/O error. */ | 13873 | signals, which can cause an apparent I/O error. */ |
| @@ -13906,8 +13921,10 @@ redisplay_internal (void) | |||
| 13906 | /* Compare desired and current matrices, perform output. */ | 13921 | /* Compare desired and current matrices, perform output. */ |
| 13907 | 13922 | ||
| 13908 | update: | 13923 | update: |
| 13909 | /* If fonts changed, display again. */ | 13924 | /* If fonts changed, display again. Likewise if redisplay_window_1 |
| 13910 | if (sf->fonts_changed) | 13925 | above caused some change (e.g., a change in faces) that requires |
| 13926 | considering the entire frame again. */ | ||
| 13927 | if (sf->fonts_changed || sf->redisplay) | ||
| 13911 | goto retry; | 13928 | goto retry; |
| 13912 | 13929 | ||
| 13913 | /* Prevent freeing of realized faces, since desired matrices are | 13930 | /* Prevent freeing of realized faces, since desired matrices are |