]> granicus.if.org Git - graphviz/commitdiff
fix: take a copy of font name when caching fonts in Pango plugin
authorMatthew Fernandez <matthew.fernandez@gmail.com>
Sat, 1 Aug 2020 16:37:20 +0000 (09:37 -0700)
committerMatthew Fernandez <matthew.fernandez@gmail.com>
Sat, 8 Aug 2020 01:48:49 +0000 (18:48 -0700)
The Pango plugin caches the last used font to save an expensive reconstruction
process each time it runs. To determine whether the cached font is eligible for
reuse, the name and size of the requested font are checked against the cache
entry. However the name of the cached font was only stored as a pointer to the
original name. The cached entry could outlive the original font, which could be
freed before a next call into the plugin. As a result, the plugin would perform
a strcmp using a stale freed pointer.

To address this we simply take a copy of the font name's string data instead of
just a pointer to it. There is no need to copy any of the other cached fields as
they are only accessed if the font name check finds the entry to be valid.

Related to #1767.

plugin/pango/gvtextlayout_pango.c

index fdb0f024ce7e639c5141efb0ccf7a828678a113e..7c72d5ccf5978a9ed8f587b3b3c14f4a8c62bcf7 100644 (file)
@@ -58,6 +58,16 @@ static char* pango_psfontResolve (PostscriptAlias* pa)
 #define FULL_MARKUP "<span weight=\"bold\" style=\"italic\" underline=\"single\"><sup><sub></sub></sup></span>"
 #endif
 
+/* strdup, exiting on failure */
+static char *xstrdup(const char *str) {
+  char *s = strdup(str);
+  if (s == NULL) {
+    fprintf(stderr, "out of memory\n");
+    abort();
+  }
+  return s;
+}
+
 static boolean pango_textlayout(textspan_t * span, char **fontpath)
 {
     static char buf[1024];  /* returned in fontpath, only good until next call */
@@ -103,7 +113,8 @@ static boolean pango_textlayout(textspan_t * span, char **fontpath)
            return FALSE;
        }
 
-       fontname = span->font->name;
+       free(fontname);
+       fontname = xstrdup(span->font->name);
        fontsize = span->font->size;
        pango_font_description_free (desc);