Avoid segfaults due to using fonts that were closed

* src/composite.c (composition_gstring_cache_clear_font): New
function.
* src/composite.h (composition_gstring_cache_clear_font): Add
prototype.
* src/font.c (font_clear_cache): When we are about to close a
font, remove from the gstring cache any lgstring that uses this
font.  (Bug#42943)
This commit is contained in:
Eli Zaretskii 2020-10-26 18:14:32 +02:00
parent cdb3c9d662
commit 634bbb61f2
3 changed files with 28 additions and 0 deletions

View file

@ -677,6 +677,27 @@ composition_gstring_from_id (ptrdiff_t id)
return HASH_VALUE (h, id);
}
/* Remove from the composition hash table every lgstring that
references the given FONT_OBJECT. */
void
composition_gstring_cache_clear_font (Lisp_Object font_object)
{
struct Lisp_Hash_Table *h = XHASH_TABLE (gstring_hash_table);
for (ptrdiff_t i = 0; i < HASH_TABLE_SIZE (h); ++i)
{
Lisp_Object k = HASH_KEY (h, i);
if (!EQ (k, Qunbound))
{
Lisp_Object gstring = HASH_VALUE (h, i);
if (EQ (LGSTRING_FONT (gstring), font_object))
hash_remove_from_table (h, k);
}
}
}
DEFUN ("clear-composition-cache", Fclear_composition_cache,
Sclear_composition_cache, 0, 0, 0,
doc: /* Internal use only.

View file

@ -332,6 +332,8 @@ extern int composition_update_it (struct composition_it *,
extern ptrdiff_t composition_adjust_point (ptrdiff_t, ptrdiff_t);
extern Lisp_Object composition_gstring_lookup_cache (Lisp_Object);
extern void composition_gstring_cache_clear_font (Lisp_Object);
INLINE_HEADER_END
#endif /* not EMACS_COMPOSITE_H */

View file

@ -2645,6 +2645,11 @@ font_clear_cache (struct frame *f, Lisp_Object cache,
if (! NILP (AREF (val, FONT_TYPE_INDEX)))
{
eassert (font && driver == font->driver);
/* We are going to close the font, so make
sure we don't have any lgstrings lying
around in lgstring cache that reference
the font. */
composition_gstring_cache_clear_font (val);
driver->close_font (font);
}
}