From: Dmitry Antipov Date: Mon, 16 Dec 2013 07:45:33 +0000 (+0400) Subject: * font.c (valid_font_driver) [ENABLE_CHECKING]: New function X-Git-Tag: emacs-24.3.90~173^2^2~42^2~45^2~387^2~395 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=5ae356d99130af32b51a0cd67d1933ed9e6cd20e;p=emacs.git * font.c (valid_font_driver) [ENABLE_CHECKING]: New function intended to find bogus pointers in font objects (Bug#16140). * font.h (valid_font_driver) [ENABLE_CHECKING]: Add prototype. * alloc.c (cleanup_vector): Use valid_font_driver in eassert. (compact_font_cache_entry, compact_font_caches) [!HAVE_NTGUI]: Disable for MS-Windows due to Bug#15876; apparently this requires more or less substantial changes in fontset code. * xfont.c (xfont_close): * xftfont.c (xftfont_close): Call x_display_info_for_display to check whether 'Display *' is valid (Bug#16093 and probably Bug#16069). --- diff --git a/src/ChangeLog b/src/ChangeLog index d5c84d04807..7b8a624d629 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,17 @@ +2013-12-16 Dmitry Antipov + + * font.c (valid_font_driver) [ENABLE_CHECKING]: New function + intended to find bogus pointers in font objects (Bug#16140). + * font.h (valid_font_driver) [ENABLE_CHECKING]: Add prototype. + * alloc.c (cleanup_vector): Use valid_font_driver in eassert. + (compact_font_cache_entry, compact_font_caches) [!HAVE_NTGUI]: + Disable for MS-Windows due to Bug#15876; apparently this + requires more or less substantial changes in fontset code. + * xfont.c (xfont_close): + * xftfont.c (xftfont_close): Call x_display_info_for_display + to check whether 'Display *' is valid (Bug#16093 and probably + Bug#16069). + 2013-12-15 Eli Zaretskii * fileio.c (Fexpand_file_name) [WINDOWSNT]: Fix conditionals. diff --git a/src/alloc.c b/src/alloc.c index aeda42637cd..447b465a076 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -2877,7 +2877,11 @@ cleanup_vector (struct Lisp_Vector *vector) if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FONT) && ((vector->header.size & PSEUDOVECTOR_SIZE_MASK) == FONT_OBJECT_MAX)) - ((struct font *) vector)->driver->close ((struct font *) vector); + { + /* Attempt to catch subtle bugs like Bug#16140. */ + eassert (valid_font_driver (((struct font *) vector)->driver)); + ((struct font *) vector)->driver->close ((struct font *) vector); + } } /* Reclaim space used by unmarked vectors. */ @@ -5299,6 +5303,10 @@ total_bytes_of_live_objects (void) #ifdef HAVE_WINDOW_SYSTEM +/* This code has a few issues on MS-Windows, see Bug#15876 and Bug#16140. */ + +#if !defined (HAVE_NTGUI) + /* Remove unmarked font-spec and font-entity objects from ENTRY, which is (DRIVER-TYPE NUM-FRAMES FONT-CACHE-DATA ...), and return changed entry. */ @@ -5337,6 +5345,8 @@ compact_font_cache_entry (Lisp_Object entry) return entry; } +#endif /* not HAVE_NTGUI */ + /* Compact font caches on all terminals and mark everything which is still here after compaction. */ @@ -5348,7 +5358,7 @@ compact_font_caches (void) for (t = terminal_list; t; t = t->next_terminal) { Lisp_Object cache = TERMINAL_FONT_CACHE (t); - +#if !defined (HAVE_NTGUI) if (CONSP (cache)) { Lisp_Object entry; @@ -5356,6 +5366,7 @@ compact_font_caches (void) for (entry = XCDR (cache); CONSP (entry); entry = XCDR (entry)) XSETCAR (entry, compact_font_cache_entry (XCAR (entry))); } +#endif /* not HAVE_NTGUI */ mark_object (cache); } } diff --git a/src/font.c b/src/font.c index fb56b3d3fb3..db55549be8c 100644 --- a/src/font.c +++ b/src/font.c @@ -148,7 +148,27 @@ static Lisp_Object font_charset_alist; here. */ static struct font_driver_list *font_driver_list; - +#ifdef ENABLE_CHECKING + +/* Used to catch bogus pointers in font objects. */ + +bool +valid_font_driver (struct font_driver *drv) +{ + Lisp_Object tail, frame; + struct font_driver_list *fdl; + + for (fdl = font_driver_list; fdl; fdl = fdl->next) + if (fdl->driver == drv) + return true; + FOR_EACH_FRAME (tail, frame) + for (fdl = XFRAME (frame)->font_driver_list; fdl; fdl = fdl->next) + if (fdl->driver == drv) + return true; + return false; +} + +#endif /* ENABLE_CHECKING */ /* Creators of font-related Lisp object. */ diff --git a/src/font.h b/src/font.h index 2c7456a2f29..8fb80a9b617 100644 --- a/src/font.h +++ b/src/font.h @@ -787,6 +787,9 @@ extern int font_unparse_fcname (Lisp_Object font, int pixel_size, char *name, int bytes); extern void register_font_driver (struct font_driver *driver, struct frame *f); extern void free_font_driver_list (struct frame *f); +#ifdef ENABLE_CHECKING +extern bool valid_font_driver (struct font_driver *); +#endif extern Lisp_Object font_update_drivers (struct frame *f, Lisp_Object list); extern Lisp_Object font_range (ptrdiff_t, ptrdiff_t, ptrdiff_t *, struct window *, struct face *, diff --git a/src/xfont.c b/src/xfont.c index d4d6ee7c10f..df69c9141bd 100644 --- a/src/xfont.c +++ b/src/xfont.c @@ -894,7 +894,10 @@ xfont_close (struct font *font) { struct xfont_info *xfi = (struct xfont_info *) font; - if (xfi->xfont) + /* This function may be called from GC when X connection is gone + (Bug#16093), and an attempt to free font resourses on invalid + display may lead to X protocol errors or segfaults. */ + if (xfi->xfont && x_display_info_for_display (xfi->display)) { block_input (); XFreeFont (xfi->display, xfi->xfont); diff --git a/src/xftfont.c b/src/xftfont.c index 37b33b3ead8..178981c4958 100644 --- a/src/xftfont.c +++ b/src/xftfont.c @@ -491,7 +491,9 @@ xftfont_close (struct font *font) } #endif - if (xftfont_info->xftfont) + /* See comment in xfont_close. */ + if (xftfont_info->xftfont + && x_display_info_for_display (xftfont_info->display)) { block_input (); XftUnlockFace (xftfont_info->xftfont);