aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPhilip2015-09-05 11:08:57 +0300
committerEli Zaretskii2015-09-05 11:08:57 +0300
commit90937cbfe48229028d839a5e8c5815020e84b235 (patch)
tree0972dc7b4397159972b951d370bbc6e2fb08f145 /src
parent8a6260e1e14ab1523c195001454c98aaa044ea64 (diff)
downloademacs-90937cbfe48229028d839a5e8c5815020e84b235.tar.gz
emacs-90937cbfe48229028d839a5e8c5815020e84b235.zip
Fix segfaults due to using a stale face ID
* src/xdisp.c (forget_escape_and_glyphless_faces): New function. (display_echo_area_1, redisplay_internal): Call it to avoid reusing stale face IDs for 'escape-glyph' and 'glyphless-char' faces, which could case a segfault if the frame's face cache was freed since the last redisplay. (Bug#21394) * src/xfaces.c (free_realized_faces): Call forget_escape_and_glyphless_faces. * src/dispextern.h (forget_escape_and_glyphless_faces): Add prototype. Copyright-paperwork-exempt: yes
Diffstat (limited to 'src')
-rw-r--r--src/dispextern.h1
-rw-r--r--src/xdisp.c22
-rw-r--r--src/xfaces.c2
3 files changed, 21 insertions, 4 deletions
diff --git a/src/dispextern.h b/src/dispextern.h
index 37ebab04ddf..e5adeab0dc0 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -3245,6 +3245,7 @@ extern ptrdiff_t compute_display_string_end (ptrdiff_t,
3245 struct bidi_string_data *); 3245 struct bidi_string_data *);
3246extern void produce_stretch_glyph (struct it *); 3246extern void produce_stretch_glyph (struct it *);
3247extern int merge_glyphless_glyph_face (struct it *); 3247extern int merge_glyphless_glyph_face (struct it *);
3248extern void forget_escape_and_glyphless_faces (void);
3248 3249
3249extern void get_font_ascent_descent (struct font *, int *, int *); 3250extern void get_font_ascent_descent (struct font *, int *, int *);
3250 3251
diff --git a/src/xdisp.c b/src/xdisp.c
index 9ff9f6ce399..82931b88e1c 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -6787,6 +6787,18 @@ merge_glyphless_glyph_face (struct it *it)
6787 return face_id; 6787 return face_id;
6788} 6788}
6789 6789
6790/* Forget the `escape-glyph' and `glyphless-char' faces. This should
6791 be called before redisplaying windows, and when the frame's face
6792 cache is freed. */
6793void
6794forget_escape_and_glyphless_faces (void)
6795{
6796 last_escape_glyph_frame = NULL;
6797 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
6798 last_glyphless_glyph_frame = NULL;
6799 last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
6800}
6801
6790/* Load IT's display element fields with information about the next 6802/* Load IT's display element fields with information about the next
6791 display element from the current position of IT. Value is false if 6803 display element from the current position of IT. Value is false if
6792 end of buffer (or C string) is reached. */ 6804 end of buffer (or C string) is reached. */
@@ -10673,6 +10685,11 @@ display_echo_area_1 (ptrdiff_t a1, Lisp_Object a2)
10673 Lisp_Object window; 10685 Lisp_Object window;
10674 struct text_pos start; 10686 struct text_pos start;
10675 10687
10688 /* We are about to enter redisplay without going through
10689 redisplay_internal, so we need to forget these faces by hand
10690 here. */
10691 forget_escape_and_glyphless_faces ();
10692
10676 /* Do this before displaying, so that we have a large enough glyph 10693 /* Do this before displaying, so that we have a large enough glyph
10677 matrix for the display. If we can't get enough space for the 10694 matrix for the display. If we can't get enough space for the
10678 whole text, display the last N lines. That works by setting w->start. */ 10695 whole text, display the last N lines. That works by setting w->start. */
@@ -13326,10 +13343,7 @@ redisplay_internal (void)
13326 sw = w; 13343 sw = w;
13327 13344
13328 pending = false; 13345 pending = false;
13329 last_escape_glyph_frame = NULL; 13346 forget_escape_and_glyphless_faces ();
13330 last_escape_glyph_face_id = (1 << FACE_ID_BITS);
13331 last_glyphless_glyph_frame = NULL;
13332 last_glyphless_glyph_face_id = (1 << FACE_ID_BITS);
13333 13347
13334 /* If face_change, init_iterator will free all realized faces, which 13348 /* If face_change, init_iterator will free all realized faces, which
13335 includes the faces referenced from current matrices. So, we 13349 includes the faces referenced from current matrices. So, we
diff --git a/src/xfaces.c b/src/xfaces.c
index d89adca8c57..03032496381 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -4173,6 +4173,8 @@ free_realized_faces (struct face_cache *c)
4173 c->faces_by_id[i] = NULL; 4173 c->faces_by_id[i] = NULL;
4174 } 4174 }
4175 4175
4176 /* Forget the escape-glyph and glyphless-char faces. */
4177 forget_escape_and_glyphless_faces ();
4176 c->used = 0; 4178 c->used = 0;
4177 size = FACE_CACHE_BUCKETS_SIZE * sizeof *c->buckets; 4179 size = FACE_CACHE_BUCKETS_SIZE * sizeof *c->buckets;
4178 memset (c->buckets, 0, size); 4180 memset (c->buckets, 0, size);