From 92481ff02739b7b6db3a6b060db49414ddfdb0ad Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Wed, 24 Feb 2021 10:33:02 -0800 Subject: fontmap: be more defensive in patterns finalization This clears a few pointers defensively in cleanup. It also uses a weak pointer on the PangoFcFontMap so that we don't dereference the raw pointer if we race during finalization. --- pango/pangofc-fontmap.c | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/pango/pangofc-fontmap.c b/pango/pangofc-fontmap.c index aa90345e..febaf51c 100644 --- a/pango/pangofc-fontmap.c +++ b/pango/pangofc-fontmap.c @@ -816,9 +816,9 @@ thread_data_free (gpointer data) ThreadData *td = data; g_clear_pointer (&td->fonts, FcFontSetDestroy); - FcPatternDestroy (td->pattern); - FcConfigDestroy (td->config); - pango_fc_patterns_unref (td->patterns); + g_clear_pointer (&td->pattern, FcPatternDestroy); + g_clear_pointer (&td->config, FcConfigDestroy); + g_clear_pointer (&td->patterns, pango_fc_patterns_unref); g_free (td); } @@ -887,6 +887,9 @@ pango_fc_patterns_new (FcPattern *pat, PangoFcFontMap *fontmap) pats->fontmap = fontmap; + g_object_add_weak_pointer (G_OBJECT (fontmap), + (gpointer *)&pats->fontmap); + pats->ref_count = 1; FcPatternReference (pat); pats->pattern = pat; @@ -932,21 +935,22 @@ pango_fc_patterns_unref (PangoFcPatterns *pats) if (pats->ref_count) return; - /* Only remove from fontmap hash if we are in it. This is not necessarily - * the case after a cache_clear() call. */ - if (pats->fontmap->priv->patterns_hash && - pats == g_hash_table_lookup (pats->fontmap->priv->patterns_hash, pats->pattern)) - g_hash_table_remove (pats->fontmap->priv->patterns_hash, - pats->pattern); - - if (pats->pattern) - FcPatternDestroy (pats->pattern); + if (pats->fontmap) + { + g_object_remove_weak_pointer (G_OBJECT (pats->fontmap), + (gpointer *)&pats->fontmap); - if (pats->match) - FcPatternDestroy (pats->match); + /* Only remove from fontmap hash if we are in it. This is not necessarily + * the case after a cache_clear() call. */ + if (pats->fontmap->priv->patterns_hash && + pats == g_hash_table_lookup (pats->fontmap->priv->patterns_hash, pats->pattern)) + g_hash_table_remove (pats->fontmap->priv->patterns_hash, + pats->pattern); + } - if (pats->fontset) - FcFontSetDestroy (pats->fontset); + g_clear_pointer (&pats->pattern, FcPatternDestroy); + g_clear_pointer (&pats->match, FcPatternDestroy); + g_clear_pointer (&pats->fontset, FcFontSetDestroy); g_cond_clear (&pats->cond); g_mutex_clear (&pats->mutex); -- cgit v1.2.1