summaryrefslogtreecommitdiff
path: root/pango/pangocoretext-fontmap.c
diff options
context:
space:
mode:
authorJeremy Tan <jtanx@outlook.com>2019-06-10 20:34:58 +0800
committerJeremy Tan <jtanx@outlook.com>2019-06-10 23:56:54 +0800
commit6b85844bc9f6dbedab6e5124039120dbc075259f (patch)
tree5575c4dc032f84f4b5d9f24ef2c4979458fd13a6 /pango/pangocoretext-fontmap.c
parent5d2d018397873d199ceb175292f3fa0e2f45a598 (diff)
downloadpango-6b85844bc9f6dbedab6e5124039120dbc075259f.tar.gz
Core text: Fix indexing into cascade list when multiple fonts are selected
Bug introduced from 633fd80. With that changeset, if multiple fonts from the provided font family are found, they are added to the start of fontset->fonts. Space for the cascade list (based on the 'best'/first font) then follows. However, pango_core_text_fontset_get_font_at was not updated to match this change. So it still assumes that there is at most only one 'real' font in fonset->fonts. With this assumption, the indexing into fontset->cascade_list became incorrect, leading to an out-of-bounds access on that list, resulting in an exception being thrown. Track the number of fonts found in pango_core_text_fontset_new in real_fount_count, and use this as the offset into cascade_list. This also fixes a memory leak; when a PangoCoreTextFontSet is initialised, fonts and coverages are pre-initialised, but this was being discarded and re-set in pango_core_text_fontset_new without freeing the previous initialisation.
Diffstat (limited to 'pango/pangocoretext-fontmap.c')
-rw-r--r--pango/pangocoretext-fontmap.c28
1 files changed, 14 insertions, 14 deletions
diff --git a/pango/pangocoretext-fontmap.c b/pango/pangocoretext-fontmap.c
index b4654268..427e9a0f 100644
--- a/pango/pangocoretext-fontmap.c
+++ b/pango/pangocoretext-fontmap.c
@@ -1528,6 +1528,7 @@ struct _PangoCoreTextFontset
GPtrArray *fonts;
GPtrArray *coverages;
+ guint real_font_count;
};
struct _PangoCoreTextFontsetClass
@@ -1558,10 +1559,9 @@ pango_core_text_fontset_new (PangoCoreTextFontsetKey *key,
gchar **family_names;
const gchar *family;
gchar *name;
- GPtrArray *fonts;
int i;
- fonts = g_ptr_array_new ();
+ fontset = g_object_new (PANGO_TYPE_CORE_TEXT_FONTSET, NULL);
family = pango_font_description_get_family (description);
family_names = g_strsplit (family ? family : "", ",", -1);
@@ -1588,7 +1588,7 @@ pango_core_text_fontset_new (PangoCoreTextFontsetKey *key,
if (font)
{
- g_ptr_array_add (fonts, font);
+ g_ptr_array_add (fontset->fonts, font);
if (best_font == NULL) best_font = font;
}
}
@@ -1599,17 +1599,15 @@ pango_core_text_fontset_new (PangoCoreTextFontsetKey *key,
if (!best_font)
{
- g_ptr_array_free (fonts, false);
+ g_object_unref (fontset);
return NULL;
}
/* Create a font set with best font */
- fontset = g_object_new (PANGO_TYPE_CORE_TEXT_FONTSET, NULL);
fontset->key = pango_core_text_fontset_key_copy (key);
fontset->orig_description = pango_font_description_copy (description);
- fontset->fonts = fonts;
- fontset->coverages = g_ptr_array_new ();
+ fontset->real_font_count = fontset->fonts->len;
/* Add the cascade list for this language */
#if defined(MAC_OS_X_VERSION_10_8) && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_8
@@ -1643,9 +1641,9 @@ pango_core_text_fontset_new (PangoCoreTextFontsetKey *key,
fontset->cascade_list = CTFontCopyDefaultCascadeList (pango_core_text_font_get_ctfont (best_font));
#endif
- /* length of cascade list + 1 for the "real" font at the front */
- g_ptr_array_set_size (fontset->fonts, CFArrayGetCount (fontset->cascade_list) + fonts->len);
- g_ptr_array_set_size (fontset->coverages, CFArrayGetCount (fontset->cascade_list) + fonts->len);
+ /* length of cascade list + real_font_count for the "real" fonts at the front */
+ g_ptr_array_set_size (fontset->fonts, CFArrayGetCount (fontset->cascade_list) + fontset->real_font_count);
+ g_ptr_array_set_size (fontset->coverages, CFArrayGetCount (fontset->cascade_list) + fontset->real_font_count);
return fontset;
}
@@ -1674,8 +1672,8 @@ static PangoFont *
pango_core_text_fontset_get_font_at (PangoCoreTextFontset *ctfontset,
unsigned int i)
{
- /* The first font is loaded as soon as the fontset is created */
- if (i == 0)
+ /* These fonts are loaded as soon as the fontset is created */
+ if (i < ctfontset->real_font_count)
return g_ptr_array_index (ctfontset->fonts, i);
if (i >= ctfontset->fonts->len)
@@ -1683,7 +1681,7 @@ pango_core_text_fontset_get_font_at (PangoCoreTextFontset *ctfontset,
if (g_ptr_array_index (ctfontset->fonts, i) == NULL)
{
- CTFontDescriptorRef ctdescriptor = CFArrayGetValueAtIndex (ctfontset->cascade_list, i - 1);
+ CTFontDescriptorRef ctdescriptor = CFArrayGetValueAtIndex (ctfontset->cascade_list, i - ctfontset->real_font_count);
PangoFont *font = pango_core_text_fontset_load_font (ctfontset, ctdescriptor);
g_ptr_array_index (ctfontset->fonts, i) = font;
g_ptr_array_index (ctfontset->coverages, i) = NULL;
@@ -1712,6 +1710,7 @@ pango_core_text_fontset_init (PangoCoreTextFontset *ctfontset)
ctfontset->cascade_list = NULL;
ctfontset->fonts = g_ptr_array_new ();
ctfontset->coverages = g_ptr_array_new ();
+ ctfontset->real_font_count = 0;
}
static void
@@ -1736,7 +1735,8 @@ pango_core_text_fontset_finalize (GObject *object)
}
g_ptr_array_free (ctfontset->coverages, TRUE);
- CFRelease (ctfontset->cascade_list);
+ if (ctfontset->cascade_list)
+ CFRelease (ctfontset->cascade_list);
pango_font_description_free (ctfontset->orig_description);