From 9df07c3c303299ea782176aad901cd7831f4e025 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 8 Jun 2023 11:46:06 -0600 Subject: [PATCH] [gsubgpos] Prevent a leak in closure If the push wasn't successful we were constructing an hb_set_t on the Crap data... At least that's my reading of the code. --- src/hb-ot-layout-gsubgpos.hh | 48 ++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index 841ff1942..4b9c3cc48 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -143,9 +143,12 @@ struct hb_closure_context_t : return active_glyphs_stack.tail (); } - hb_set_t& push_cur_active_glyphs () + hb_set_t* push_cur_active_glyphs () { - return *active_glyphs_stack.push (); + hb_set_t *s = active_glyphs_stack.push (); + if (unlikely (active_glyphs_stack.in_error ())) + return nullptr; + return s; } bool pop_cur_done_glyphs () @@ -1615,10 +1618,13 @@ static void context_closure_recurse_lookups (hb_closure_context_t *c, } covered_seq_indicies.add (seqIndex); + hb_set_t *cur_active_glyphs = c->push_cur_active_glyphs (); + if (unlikely (!cur_active_glyphs)) + return; if (has_pos_glyphs) { - c->push_cur_active_glyphs () = std::move (pos_glyphs); + *cur_active_glyphs = std::move (pos_glyphs); } else { - c->push_cur_active_glyphs ().set (*c->glyphs); + *cur_active_glyphs = *c->glyphs; } unsigned endIndex = inputCount; @@ -2168,8 +2174,9 @@ struct ContextFormat1_4 void closure (hb_closure_context_t *c) const { - hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs (); - get_coverage ().intersect_set (c->previous_parent_active_glyphs (), cur_active_glyphs); + hb_set_t* cur_active_glyphs = c->push_cur_active_glyphs (); + if (unlikely (!cur_active_glyphs)) return; + get_coverage ().intersect_set (c->previous_parent_active_glyphs (), *cur_active_glyphs); struct ContextClosureLookupContext lookup_context = { {intersects_glyph, intersected_glyph}, @@ -2338,9 +2345,10 @@ struct ContextFormat2_5 if (!(this+coverage).intersects (c->glyphs)) return; - hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs (); + hb_set_t* cur_active_glyphs = c->push_cur_active_glyphs (); + if (unlikely (!cur_active_glyphs)) return; get_coverage ().intersect_set (c->previous_parent_active_glyphs (), - cur_active_glyphs); + *cur_active_glyphs); const ClassDef &class_def = this+classDef; @@ -2583,10 +2591,10 @@ struct ContextFormat3 if (!(this+coverageZ[0]).intersects (c->glyphs)) return; - hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs (); + hb_set_t* cur_active_glyphs = c->push_cur_active_glyphs (); + if (unlikely (!cur_active_glyphs)) return; get_coverage ().intersect_set (c->previous_parent_active_glyphs (), - cur_active_glyphs); - + *cur_active_glyphs); const LookupRecord *lookupRecord = &StructAfter (coverageZ.as_array (glyphCount)); struct ContextClosureLookupContext lookup_context = { @@ -3249,9 +3257,10 @@ struct ChainContextFormat1_4 void closure (hb_closure_context_t *c) const { - hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs (); + hb_set_t* cur_active_glyphs = c->push_cur_active_glyphs (); + if (unlikely (!cur_active_glyphs)) return; get_coverage ().intersect_set (c->previous_parent_active_glyphs (), - cur_active_glyphs); + *cur_active_glyphs); struct ChainContextClosureLookupContext lookup_context = { {intersects_glyph, intersected_glyph}, @@ -3421,10 +3430,10 @@ struct ChainContextFormat2_5 if (!(this+coverage).intersects (c->glyphs)) return; - hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs (); + hb_set_t* cur_active_glyphs = c->push_cur_active_glyphs (); + if (unlikely (!cur_active_glyphs)) return; get_coverage ().intersect_set (c->previous_parent_active_glyphs (), - cur_active_glyphs); - + *cur_active_glyphs); const ClassDef &backtrack_class_def = this+backtrackClassDef; const ClassDef &input_class_def = this+inputClassDef; @@ -3725,10 +3734,11 @@ struct ChainContextFormat3 if (!(this+input[0]).intersects (c->glyphs)) return; - hb_set_t& cur_active_glyphs = c->push_cur_active_glyphs (); + hb_set_t* cur_active_glyphs = c->push_cur_active_glyphs (); + if (unlikely (!cur_active_glyphs)) + return; get_coverage ().intersect_set (c->previous_parent_active_glyphs (), - cur_active_glyphs); - + *cur_active_glyphs); const auto &lookahead = StructAfter (input); const auto &lookup = StructAfter (lookahead);