aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDmitry Antipov2014-03-03 12:27:58 +0400
committerDmitry Antipov2014-03-03 12:27:58 +0400
commit19dae293f9fecea07c91440f0a33076c54d39b49 (patch)
treee2ef81c52b8c2dc8ffad510110f3bc71b2b3524f /src
parent8c1c761122b7472617c82fd00c949df52260c903 (diff)
downloademacs-19dae293f9fecea07c91440f0a33076c54d39b49.tar.gz
emacs-19dae293f9fecea07c91440f0a33076c54d39b49.zip
Avoid crashes when X fonts are erroneously freed on reused X
'Display *' connection data (Bug#16069). Note that X font resources still may be leaked, but currently there is no way to completely avoid it. * xterm.h (struct x_display_info): New member x_id. Add comments. * xterm.c (x_display_id): New variable. (x_term_init): Assign identifier to each opened X connection. * xfont.c (struct xfont): New member x_display_id. (xfont_open): Initialize it with frame's display id. (xfont_close): Check whether font's display id matches the one recorded for the given display. Adjust comment. * xftfont.c (struct xftfont_info): (xftfont_open, xftfont_close): Exactly as above with xfont stuff.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog14
-rw-r--r--src/xfont.c14
-rw-r--r--src/xftfont.c6
-rw-r--r--src/xterm.c5
-rw-r--r--src/xterm.h4
5 files changed, 40 insertions, 3 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 280077c3844..7bc69b2894e 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -6,6 +6,20 @@
6 (Fframe_font_cache) [FONT_DEBUG]: New function. 6 (Fframe_font_cache) [FONT_DEBUG]: New function.
7 (syms_of_font) [FONT_DEBUG]: Defsubr it. 7 (syms_of_font) [FONT_DEBUG]: Defsubr it.
8 8
9 Avoid crashes when X fonts are erroneously freed on reused X
10 'Display *' connection data (Bug#16069). Note that X font
11 resources still may be leaked, but currently there is no way
12 to completely avoid it.
13 * xterm.h (struct x_display_info): New member x_id. Add comments.
14 * xterm.c (x_display_id): New variable.
15 (x_term_init): Assign identifier to each opened X connection.
16 * xfont.c (struct xfont): New member x_display_id.
17 (xfont_open): Initialize it with frame's display id.
18 (xfont_close): Check whether font's display id matches the one
19 recorded for the given display. Adjust comment.
20 * xftfont.c (struct xftfont_info):
21 (xftfont_open, xftfont_close): Exactly as above with xfont stuff.
22
92014-03-01 Martin Rudalics <rudalics@gmx.at> 232014-03-01 Martin Rudalics <rudalics@gmx.at>
10 24
11 Consider Vother_window_scroll_buffer valid iff it's a live buffer. 25 Consider Vother_window_scroll_buffer valid iff it's a live buffer.
diff --git a/src/xfont.c b/src/xfont.c
index 3295a62bbb0..525f00031c5 100644
--- a/src/xfont.c
+++ b/src/xfont.c
@@ -42,6 +42,7 @@ struct xfont_info
42 struct font font; 42 struct font font;
43 Display *display; 43 Display *display;
44 XFontStruct *xfont; 44 XFontStruct *xfont;
45 unsigned x_display_id;
45}; 46};
46 47
47/* Prototypes of support functions. */ 48/* Prototypes of support functions. */
@@ -808,6 +809,7 @@ xfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
808 font = XFONT_OBJECT (font_object); 809 font = XFONT_OBJECT (font_object);
809 ((struct xfont_info *) font)->xfont = xfont; 810 ((struct xfont_info *) font)->xfont = xfont;
810 ((struct xfont_info *) font)->display = FRAME_X_DISPLAY (f); 811 ((struct xfont_info *) font)->display = FRAME_X_DISPLAY (f);
812 ((struct xfont_info *) font)->x_display_id = FRAME_DISPLAY_INFO (f)->x_id;
811 font->pixel_size = pixel_size; 813 font->pixel_size = pixel_size;
812 font->driver = &xfont_driver; 814 font->driver = &xfont_driver;
813 font->encoding_charset = encoding->id; 815 font->encoding_charset = encoding->id;
@@ -892,12 +894,20 @@ xfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
892static void 894static void
893xfont_close (struct font *font) 895xfont_close (struct font *font)
894{ 896{
897 struct x_display_info *xdi;
895 struct xfont_info *xfi = (struct xfont_info *) font; 898 struct xfont_info *xfi = (struct xfont_info *) font;
896 899
897 /* This function may be called from GC when X connection is gone 900 /* This function may be called from GC when X connection is gone
898 (Bug#16093), and an attempt to free font resources on invalid 901 (Bug#16093), and an attempt to free font resources on invalid
899 display may lead to X protocol errors or segfaults. */ 902 display may lead to X protocol errors or segfaults. Moreover,
900 if (xfi->xfont && x_display_info_for_display (xfi->display)) 903 the memory referenced by 'Display *' pointer may be reused for
904 the logically different X connection after the previous display
905 connection was closed. That's why we also check whether font's
906 ID matches the one recorded in x_display_info for this display.
907 See http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16069. */
908 if (xfi->xfont
909 && ((xdi = x_display_info_for_display (xfi->display))
910 && xfi->x_display_id == xdi->x_id))
901 { 911 {
902 block_input (); 912 block_input ();
903 XFreeFont (xfi->display, xfi->xfont); 913 XFreeFont (xfi->display, xfi->xfont);
diff --git a/src/xftfont.c b/src/xftfont.c
index 32816b97f23..18c180f906a 100644
--- a/src/xftfont.c
+++ b/src/xftfont.c
@@ -59,6 +59,7 @@ struct xftfont_info
59 FT_Matrix matrix; 59 FT_Matrix matrix;
60 Display *display; 60 Display *display;
61 XftFont *xftfont; 61 XftFont *xftfont;
62 unsigned x_display_id;
62}; 63};
63 64
64/* Structure pointed by (struct face *)->extra */ 65/* Structure pointed by (struct face *)->extra */
@@ -372,6 +373,7 @@ xftfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
372 xftfont_info = (struct xftfont_info *) font; 373 xftfont_info = (struct xftfont_info *) font;
373 xftfont_info->display = display; 374 xftfont_info->display = display;
374 xftfont_info->xftfont = xftfont; 375 xftfont_info->xftfont = xftfont;
376 xftfont_info->x_display_id = FRAME_DISPLAY_INFO (f)->x_id;
375 /* This means that there's no need of transformation. */ 377 /* This means that there's no need of transformation. */
376 xftfont_info->matrix.xx = 0; 378 xftfont_info->matrix.xx = 0;
377 if (FcPatternGetMatrix (xftfont->pattern, FC_MATRIX, 0, &matrix) 379 if (FcPatternGetMatrix (xftfont->pattern, FC_MATRIX, 0, &matrix)
@@ -481,6 +483,7 @@ xftfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
481static void 483static void
482xftfont_close (struct font *font) 484xftfont_close (struct font *font)
483{ 485{
486 struct x_display_info *xdi;
484 struct xftfont_info *xftfont_info = (struct xftfont_info *) font; 487 struct xftfont_info *xftfont_info = (struct xftfont_info *) font;
485 488
486#ifdef HAVE_LIBOTF 489#ifdef HAVE_LIBOTF
@@ -493,7 +496,8 @@ xftfont_close (struct font *font)
493 496
494 /* See comment in xfont_close. */ 497 /* See comment in xfont_close. */
495 if (xftfont_info->xftfont 498 if (xftfont_info->xftfont
496 && x_display_info_for_display (xftfont_info->display)) 499 && ((xdi = x_display_info_for_display (xftfont_info->display))
500 && xftfont_info->x_display_id == xdi->x_id))
497 { 501 {
498 block_input (); 502 block_input ();
499 XftUnlockFace (xftfont_info->xftfont); 503 XftUnlockFace (xftfont_info->xftfont);
diff --git a/src/xterm.c b/src/xterm.c
index e1873127276..f06225002a7 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -9679,6 +9679,10 @@ my_log_handler (const gchar *log_domain, GLogLevelFlags log_level,
9679} 9679}
9680#endif 9680#endif
9681 9681
9682/* Current X display connection identifier. Incremented for each next
9683 connection established. */
9684static unsigned x_display_id;
9685
9682/* Open a connection to X display DISPLAY_NAME, and return 9686/* Open a connection to X display DISPLAY_NAME, and return
9683 the structure that describes the open display. 9687 the structure that describes the open display.
9684 If we cannot contact the display, return null. */ 9688 If we cannot contact the display, return null. */
@@ -9896,6 +9900,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
9896 lim = min (PTRDIFF_MAX, SIZE_MAX) - sizeof "@"; 9900 lim = min (PTRDIFF_MAX, SIZE_MAX) - sizeof "@";
9897 if (lim - SBYTES (Vinvocation_name) < SBYTES (Vsystem_name)) 9901 if (lim - SBYTES (Vinvocation_name) < SBYTES (Vsystem_name))
9898 memory_full (SIZE_MAX); 9902 memory_full (SIZE_MAX);
9903 dpyinfo->x_id = ++x_display_id;
9899 dpyinfo->x_id_name = xmalloc (SBYTES (Vinvocation_name) 9904 dpyinfo->x_id_name = xmalloc (SBYTES (Vinvocation_name)
9900 + SBYTES (Vsystem_name) + 2); 9905 + SBYTES (Vsystem_name) + 2);
9901 strcat (strcat (strcpy (dpyinfo->x_id_name, SSDATA (Vinvocation_name)), "@"), 9906 strcat (strcat (strcpy (dpyinfo->x_id_name, SSDATA (Vinvocation_name)), "@"),
diff --git a/src/xterm.h b/src/xterm.h
index 3e79d46702c..50df88cb592 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -198,6 +198,10 @@ struct x_display_info
198 mouse-face. */ 198 mouse-face. */
199 Mouse_HLInfo mouse_highlight; 199 Mouse_HLInfo mouse_highlight;
200 200
201 /* Logical identifier of this display. */
202 unsigned x_id;
203
204 /* Default name for all frames on this display. */
201 char *x_id_name; 205 char *x_id_name;
202 206
203 /* The number of fonts opened for this display. */ 207 /* The number of fonts opened for this display. */