[subset] track which glyphs have allocated memory so we can clean up correctly.

Fixes https://oss-fuzz.com/testcase-detail/5388270411579392
This commit is contained in:
Garret Rieger 2023-03-13 21:34:26 +00:00 committed by Behdad Esfahbod
parent 7a87b17742
commit 3d05b96181
4 changed files with 16 additions and 8 deletions

View File

@ -330,7 +330,10 @@ struct CompositeGlyph
for (const auto &component : it) for (const auto &component : it)
{ {
/* last 4 points in deltas are phantom points and should not be included */ /* last 4 points in deltas are phantom points and should not be included */
if (i >= deltas.length - 4) return false; if (i >= deltas.length - 4) {
free (o);
return false;
}
unsigned comp_len = component.get_size (); unsigned comp_len = component.get_size ();
if (component.is_anchored ()) if (component.is_anchored ())

View File

@ -18,6 +18,7 @@ struct SubsetGlyph
Glyph source_glyph; Glyph source_glyph;
hb_bytes_t dest_start; /* region of source_glyph to copy first */ hb_bytes_t dest_start; /* region of source_glyph to copy first */
hb_bytes_t dest_end; /* region of source_glyph to copy second */ hb_bytes_t dest_end; /* region of source_glyph to copy second */
bool allocated;
bool serialize (hb_serialize_context_t *c, bool serialize (hb_serialize_context_t *c,
bool use_short_loca, bool use_short_loca,
@ -60,13 +61,19 @@ struct SubsetGlyph
bool compile_bytes_with_deltas (const hb_subset_plan_t *plan, bool compile_bytes_with_deltas (const hb_subset_plan_t *plan,
hb_font_t *font, hb_font_t *font,
const glyf_accelerator_t &glyf) const glyf_accelerator_t &glyf)
{ return source_glyph.compile_bytes_with_deltas (plan, font, glyf, dest_start, dest_end); } {
allocated = source_glyph.compile_bytes_with_deltas (plan, font, glyf, dest_start, dest_end);
return allocated;
}
void free_compiled_bytes () void free_compiled_bytes ()
{ {
if (likely (allocated)) {
allocated = false;
dest_start.fini (); dest_start.fini ();
dest_end.fini (); dest_end.fini ();
} }
}
void drop_hints_bytes () void drop_hints_bytes ()
{ source_glyph.drop_hints_bytes (dest_start, dest_end); } { source_glyph.drop_hints_bytes (dest_start, dest_end); }

View File

@ -424,7 +424,6 @@ glyf::_populate_subset_glyphs (const hb_subset_plan_t *plan,
unsigned num_glyphs = plan->num_output_glyphs (); unsigned num_glyphs = plan->num_output_glyphs ();
if (!glyphs.resize (num_glyphs)) return false; if (!glyphs.resize (num_glyphs)) return false;
unsigned idx = 0;
for (auto p : plan->glyph_map->iter ()) for (auto p : plan->glyph_map->iter ())
{ {
unsigned new_gid = p.second; unsigned new_gid = p.second;
@ -452,11 +451,10 @@ glyf::_populate_subset_glyphs (const hb_subset_plan_t *plan,
if (unlikely (!subset_glyph.compile_bytes_with_deltas (plan, font, glyf))) if (unlikely (!subset_glyph.compile_bytes_with_deltas (plan, font, glyf)))
{ {
// when pinned at default, only bounds are updated, thus no need to free // when pinned at default, only bounds are updated, thus no need to free
if (!plan->pinned_at_default && idx > 0) if (!plan->pinned_at_default)
_free_compiled_subset_glyphs (glyphs, idx - 1); _free_compiled_subset_glyphs (glyphs, new_gid);
return false; return false;
} }
idx++;
} }
} }
return true; return true;