<div dir="ltr"><div class="gmail_default" style="font-family:tahoma,sans-serif">I think I found a bug concerning non-released memory when using font variations.<br>I tested against cairo-1.17.2. <br></div><div class="gmail_default" style="font-family:tahoma,sans-serif"><br></div><div class="gmail_default" style="font-family:tahoma,sans-serif">The internal function _cairo_gstate_init_copy() is supposed to make a deep copy of the fields from one instance/state to another, used for example by cairo_save(). It does however call _cairo_font_options_init_copy(), which has this line in it:<br>options->variations = other->variations ? strdup (other->variations) : NULL;<br><br>This means that if a font variation string has been set, instead of a copy, it will always allocate and use a copy of the string (via strdup), which will then never be freed.<br>This leads to memory leaks as for example just by calling cairo_save(), with each call an additional pointer is created that is never released.<br><br>Simple sample code to reproduce:</div><div class="gmail_default" style="font-family:tahoma,sans-serif"> cairo_surface_t* surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1920, 1080);<br> cairo_t* cr = cairo_create(surface);<br> </div><div class="gmail_default" style="font-family:tahoma,sans-serif">cairo_font_options_t* t = cairo_font_options_create();<br> cairo_get_font_options(cr, t);<br>cairo_font_options_set_variations(t, "wght=400");<br> cairo_set_font_options(cr, t);<br> cairo_font_options_destroy(t);<br> cairo_save(cr);<br> cairo_restore(cr);
<div class="gmail_default" style="font-family:tahoma,sans-serif">cairo_destroy(cr);<br> cairo_surface_destroy(surface);<br></div>
</div><div class="gmail_default" style="font-family:tahoma,sans-serif"></div><div class="gmail_default" style="font-family:tahoma,sans-serif"><br></div><div class="gmail_default" style="font-family:tahoma,sans-serif">I think what is missing is a matching free-and-null call in
_cairo_gstate_fini().</div><div class="gmail_default" style="font-family:tahoma,sans-serif"></div><div class="gmail_default" style="font-family:tahoma,sans-serif">If I add the following two lines at the beginning of_cairo_gstate_fini(), it seems to fix this issue, as every allocated copy gets freed again:<br>_cairo_font_options_fini (&gstate->font_options);<br> gstate->font_options.variations = NULL;</div><div class="gmail_default" style="font-family:tahoma,sans-serif"><br></div><div class="gmail_default" style="font-family:tahoma,sans-serif">Let me know if this makes sense.</div><div class="gmail_default" style="font-family:tahoma,sans-serif">Cheers,</div><div class="gmail_default" style="font-family:tahoma,sans-serif">Toby<br></div></div>