From 3a43603ecea2c349f58396e103a52948776681e0 Mon Sep 17 00:00:00 2001 From: Rod Sheeter Date: Mon, 20 May 2019 20:40:55 -0700 Subject: [PATCH] [subset] Fix memory leak caused by failure to cleanup glyf accelerator --- src/hb-ot-glyf-table.hh | 46 +++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/src/hb-ot-glyf-table.hh b/src/hb-ot-glyf-table.hh index c9b9cf499..4d45a93c7 100644 --- a/src/hb-ot-glyf-table.hh +++ b/src/hb-ot-glyf-table.hh @@ -148,28 +148,11 @@ struct glyf glyf *glyf_prime = c->serializer->start_embed (); if (unlikely (!glyf_prime)) return_trace (false); - OT::glyf::accelerator_t glyf; - glyf.init (c->plan->source); - // Byte region(s) per glyph to output // unpadded, hints removed if so requested // If we fail to process a glyph we produce an empty (0-length) glyph hb_vector_t glyphs; - + hb_range (c->plan->num_output_glyphs ()) - | hb_map ([&] (hb_codepoint_t new_gid) { - SubsetGlyph subset_glyph; - subset_glyph.new_gid = new_gid; - - // should never fail: all old gids should be mapped - if (!c->plan->old_gid_for_new_gid (new_gid, &subset_glyph.old_gid)) return subset_glyph; - - subset_glyph.source_glyph = glyf.bytes_for_glyph ((const char *) this, subset_glyph.old_gid); - if (c->plan->drop_hints) subset_glyph.drop_hints (glyf); - else subset_glyph.dest_start = subset_glyph.source_glyph; - - return subset_glyph; - }) - | hb_sink (glyphs); + _populate_subset_glyphs (c->plan, &glyphs); glyf_prime->serialize (c->serializer, hb_iter (glyphs), c->plan); @@ -183,6 +166,33 @@ struct glyf return_trace (true); } + template + void + _populate_subset_glyphs (const hb_subset_plan_t * plan, + hb_vector_t * glyphs /* OUT */) const + { + OT::glyf::accelerator_t glyf; + glyf.init (plan->source); + + + hb_range (plan->num_output_glyphs ()) + | hb_map ([&] (hb_codepoint_t new_gid) { + SubsetGlyph subset_glyph; + subset_glyph.new_gid = new_gid; + + // should never fail: all old gids should be mapped + if (!plan->old_gid_for_new_gid (new_gid, &subset_glyph.old_gid)) return subset_glyph; + + subset_glyph.source_glyph = glyf.bytes_for_glyph ((const char *) this, subset_glyph.old_gid); + if (plan->drop_hints) subset_glyph.drop_hints (glyf); + else subset_glyph.dest_start = subset_glyph.source_glyph; + + return subset_glyph; + }) + | hb_sink (glyphs); + + glyf.fini(); + } + static void _fix_component_gids (const hb_subset_plan_t *plan, hb_bytes_t glyph)