<div dir="auto"><div dir="auto">Thanks Tobias. This definitely makes sense. Thanks for debugging. I'll try to take a look on computer and fix. Unless, I hope, someone beats me to that.</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Jun 10, 2020, 10:25 PM Tobias Fleischer (reduxFX) <<a href="mailto:tobias.fleischer@reduxfx.com" target="_blank" rel="noreferrer">tobias.fleischer@reduxfx.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><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>
-- <br>
cairo mailing list<br>
<a href="mailto:cairo@cairographics.org" rel="noreferrer noreferrer" target="_blank">cairo@cairographics.org</a><br>
<a href="https://lists.cairographics.org/mailman/listinfo/cairo" rel="noreferrer noreferrer noreferrer" target="_blank">https://lists.cairographics.org/mailman/listinfo/cairo</a><br>
</blockquote></div></div>