* 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).
This commit is contained in:
Dmitry Antipov 2013-12-16 11:45:33 +04:00
parent 2013a2f955
commit 5ae356d991
6 changed files with 58 additions and 5 deletions

View file

@ -1,3 +1,17 @@
2013-12-16 Dmitry Antipov <dmantipov@yandex.ru>
* 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 <eliz@gnu.org>
* fileio.c (Fexpand_file_name) [WINDOWSNT]: Fix conditionals.

View file

@ -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);
}
}

View file

@ -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. */

View file

@ -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 *,

View file

@ -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);

View file

@ -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);