[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:
parent
7a87b17742
commit
3d05b96181
|
@ -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 ())
|
||||||
|
|
|
@ -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); }
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Binary file not shown.
Loading…
Reference in New Issue