diff options
| author | Dmitry Antipov | 2013-12-16 11:45:33 +0400 |
|---|---|---|
| committer | Dmitry Antipov | 2013-12-16 11:45:33 +0400 |
| commit | 5ae356d99130af32b51a0cd67d1933ed9e6cd20e (patch) | |
| tree | 4d68dfd538ce4a7ef56027218f5ec1582d5b73df /src | |
| parent | 2013a2f955e4dc6edf9869767e9f5d70fbf9d69c (diff) | |
| download | emacs-5ae356d99130af32b51a0cd67d1933ed9e6cd20e.tar.gz emacs-5ae356d99130af32b51a0cd67d1933ed9e6cd20e.zip | |
* 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).
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 14 | ||||
| -rw-r--r-- | src/alloc.c | 15 | ||||
| -rw-r--r-- | src/font.c | 22 | ||||
| -rw-r--r-- | src/font.h | 3 | ||||
| -rw-r--r-- | src/xfont.c | 5 | ||||
| -rw-r--r-- | src/xftfont.c | 4 |
6 files changed, 58 insertions, 5 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index d5c84d04807..7b8a624d629 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,17 @@ | |||
| 1 | 2013-12-16 Dmitry Antipov <dmantipov@yandex.ru> | ||
| 2 | |||
| 3 | * font.c (valid_font_driver) [ENABLE_CHECKING]: New function | ||
| 4 | intended to find bogus pointers in font objects (Bug#16140). | ||
| 5 | * font.h (valid_font_driver) [ENABLE_CHECKING]: Add prototype. | ||
| 6 | * alloc.c (cleanup_vector): Use valid_font_driver in eassert. | ||
| 7 | (compact_font_cache_entry, compact_font_caches) [!HAVE_NTGUI]: | ||
| 8 | Disable for MS-Windows due to Bug#15876; apparently this | ||
| 9 | requires more or less substantial changes in fontset code. | ||
| 10 | * xfont.c (xfont_close): | ||
| 11 | * xftfont.c (xftfont_close): Call x_display_info_for_display | ||
| 12 | to check whether 'Display *' is valid (Bug#16093 and probably | ||
| 13 | Bug#16069). | ||
| 14 | |||
| 1 | 2013-12-15 Eli Zaretskii <eliz@gnu.org> | 15 | 2013-12-15 Eli Zaretskii <eliz@gnu.org> |
| 2 | 16 | ||
| 3 | * fileio.c (Fexpand_file_name) [WINDOWSNT]: Fix conditionals. | 17 | * 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) | |||
| 2877 | if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FONT) | 2877 | if (PSEUDOVECTOR_TYPEP (&vector->header, PVEC_FONT) |
| 2878 | && ((vector->header.size & PSEUDOVECTOR_SIZE_MASK) | 2878 | && ((vector->header.size & PSEUDOVECTOR_SIZE_MASK) |
| 2879 | == FONT_OBJECT_MAX)) | 2879 | == FONT_OBJECT_MAX)) |
| 2880 | ((struct font *) vector)->driver->close ((struct font *) vector); | 2880 | { |
| 2881 | /* Attempt to catch subtle bugs like Bug#16140. */ | ||
| 2882 | eassert (valid_font_driver (((struct font *) vector)->driver)); | ||
| 2883 | ((struct font *) vector)->driver->close ((struct font *) vector); | ||
| 2884 | } | ||
| 2881 | } | 2885 | } |
| 2882 | 2886 | ||
| 2883 | /* Reclaim space used by unmarked vectors. */ | 2887 | /* Reclaim space used by unmarked vectors. */ |
| @@ -5299,6 +5303,10 @@ total_bytes_of_live_objects (void) | |||
| 5299 | 5303 | ||
| 5300 | #ifdef HAVE_WINDOW_SYSTEM | 5304 | #ifdef HAVE_WINDOW_SYSTEM |
| 5301 | 5305 | ||
| 5306 | /* This code has a few issues on MS-Windows, see Bug#15876 and Bug#16140. */ | ||
| 5307 | |||
| 5308 | #if !defined (HAVE_NTGUI) | ||
| 5309 | |||
| 5302 | /* Remove unmarked font-spec and font-entity objects from ENTRY, which is | 5310 | /* Remove unmarked font-spec and font-entity objects from ENTRY, which is |
| 5303 | (DRIVER-TYPE NUM-FRAMES FONT-CACHE-DATA ...), and return changed entry. */ | 5311 | (DRIVER-TYPE NUM-FRAMES FONT-CACHE-DATA ...), and return changed entry. */ |
| 5304 | 5312 | ||
| @@ -5337,6 +5345,8 @@ compact_font_cache_entry (Lisp_Object entry) | |||
| 5337 | return entry; | 5345 | return entry; |
| 5338 | } | 5346 | } |
| 5339 | 5347 | ||
| 5348 | #endif /* not HAVE_NTGUI */ | ||
| 5349 | |||
| 5340 | /* Compact font caches on all terminals and mark | 5350 | /* Compact font caches on all terminals and mark |
| 5341 | everything which is still here after compaction. */ | 5351 | everything which is still here after compaction. */ |
| 5342 | 5352 | ||
| @@ -5348,7 +5358,7 @@ compact_font_caches (void) | |||
| 5348 | for (t = terminal_list; t; t = t->next_terminal) | 5358 | for (t = terminal_list; t; t = t->next_terminal) |
| 5349 | { | 5359 | { |
| 5350 | Lisp_Object cache = TERMINAL_FONT_CACHE (t); | 5360 | Lisp_Object cache = TERMINAL_FONT_CACHE (t); |
| 5351 | 5361 | #if !defined (HAVE_NTGUI) | |
| 5352 | if (CONSP (cache)) | 5362 | if (CONSP (cache)) |
| 5353 | { | 5363 | { |
| 5354 | Lisp_Object entry; | 5364 | Lisp_Object entry; |
| @@ -5356,6 +5366,7 @@ compact_font_caches (void) | |||
| 5356 | for (entry = XCDR (cache); CONSP (entry); entry = XCDR (entry)) | 5366 | for (entry = XCDR (cache); CONSP (entry); entry = XCDR (entry)) |
| 5357 | XSETCAR (entry, compact_font_cache_entry (XCAR (entry))); | 5367 | XSETCAR (entry, compact_font_cache_entry (XCAR (entry))); |
| 5358 | } | 5368 | } |
| 5369 | #endif /* not HAVE_NTGUI */ | ||
| 5359 | mark_object (cache); | 5370 | mark_object (cache); |
| 5360 | } | 5371 | } |
| 5361 | } | 5372 | } |
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; | |||
| 148 | here. */ | 148 | here. */ |
| 149 | static struct font_driver_list *font_driver_list; | 149 | static struct font_driver_list *font_driver_list; |
| 150 | 150 | ||
| 151 | 151 | #ifdef ENABLE_CHECKING | |
| 152 | |||
| 153 | /* Used to catch bogus pointers in font objects. */ | ||
| 154 | |||
| 155 | bool | ||
| 156 | valid_font_driver (struct font_driver *drv) | ||
| 157 | { | ||
| 158 | Lisp_Object tail, frame; | ||
| 159 | struct font_driver_list *fdl; | ||
| 160 | |||
| 161 | for (fdl = font_driver_list; fdl; fdl = fdl->next) | ||
| 162 | if (fdl->driver == drv) | ||
| 163 | return true; | ||
| 164 | FOR_EACH_FRAME (tail, frame) | ||
| 165 | for (fdl = XFRAME (frame)->font_driver_list; fdl; fdl = fdl->next) | ||
| 166 | if (fdl->driver == drv) | ||
| 167 | return true; | ||
| 168 | return false; | ||
| 169 | } | ||
| 170 | |||
| 171 | #endif /* ENABLE_CHECKING */ | ||
| 152 | 172 | ||
| 153 | /* Creators of font-related Lisp object. */ | 173 | /* Creators of font-related Lisp object. */ |
| 154 | 174 | ||
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, | |||
| 787 | char *name, int bytes); | 787 | char *name, int bytes); |
| 788 | extern void register_font_driver (struct font_driver *driver, struct frame *f); | 788 | extern void register_font_driver (struct font_driver *driver, struct frame *f); |
| 789 | extern void free_font_driver_list (struct frame *f); | 789 | extern void free_font_driver_list (struct frame *f); |
| 790 | #ifdef ENABLE_CHECKING | ||
| 791 | extern bool valid_font_driver (struct font_driver *); | ||
| 792 | #endif | ||
| 790 | extern Lisp_Object font_update_drivers (struct frame *f, Lisp_Object list); | 793 | extern Lisp_Object font_update_drivers (struct frame *f, Lisp_Object list); |
| 791 | extern Lisp_Object font_range (ptrdiff_t, ptrdiff_t, ptrdiff_t *, | 794 | extern Lisp_Object font_range (ptrdiff_t, ptrdiff_t, ptrdiff_t *, |
| 792 | struct window *, struct face *, | 795 | 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) | |||
| 894 | { | 894 | { |
| 895 | struct xfont_info *xfi = (struct xfont_info *) font; | 895 | struct xfont_info *xfi = (struct xfont_info *) font; |
| 896 | 896 | ||
| 897 | if (xfi->xfont) | 897 | /* This function may be called from GC when X connection is gone |
| 898 | (Bug#16093), and an attempt to free font resourses on invalid | ||
| 899 | display may lead to X protocol errors or segfaults. */ | ||
| 900 | if (xfi->xfont && x_display_info_for_display (xfi->display)) | ||
| 898 | { | 901 | { |
| 899 | block_input (); | 902 | block_input (); |
| 900 | XFreeFont (xfi->display, xfi->xfont); | 903 | 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) | |||
| 491 | } | 491 | } |
| 492 | #endif | 492 | #endif |
| 493 | 493 | ||
| 494 | if (xftfont_info->xftfont) | 494 | /* See comment in xfont_close. */ |
| 495 | if (xftfont_info->xftfont | ||
| 496 | && x_display_info_for_display (xftfont_info->display)) | ||
| 495 | { | 497 | { |
| 496 | block_input (); | 498 | block_input (); |
| 497 | XftUnlockFace (xftfont_info->xftfont); | 499 | XftUnlockFace (xftfont_info->xftfont); |