[COLR] Avoid infinite-loop through PaintColrLayers

Fixes https://github.com/harfbuzz/harfbuzz/issues/4376
Fixes https://oss-fuzz.com/testcase-detail/5717524023738368
This commit is contained in:
Behdad Esfahbod 2023-08-15 11:27:19 -06:00
parent 0c80aec10b
commit 8f039ab4d6
2 changed files with 18 additions and 0 deletions

View file

@ -70,6 +70,7 @@ public:
hb_color_t foreground;
VarStoreInstancer &instancer;
hb_set_t current_glyphs;
hb_set_t current_layers;
int depth_left = HB_MAX_NESTING_LEVEL;
int edge_count = HB_COLRV1_MAX_EDGE_COUNT;
@ -2428,10 +2429,17 @@ void PaintColrLayers::paint_glyph (hb_paint_context_t *c) const
const LayerList &paint_offset_lists = c->get_colr_table ()->get_layerList ();
for (unsigned i = firstLayerIndex; i < firstLayerIndex + numLayers; i++)
{
if (unlikely (c->current_layers.has (i)))
continue;
c->current_layers.add (i);
const Paint &paint = paint_offset_lists.get_paint (i);
c->funcs->push_group (c->data);
c->recurse (paint);
c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER);
c->current_layers.del (i);
}
}

View file

@ -106,6 +106,7 @@ struct hb_ft_paint_context_t
unsigned palette_index;
hb_color_t foreground;
hb_set_t current_glyphs;
hb_set_t current_layers;
int depth_left = HB_MAX_NESTING_LEVEL;
int edge_count = HB_COLRV1_MAX_EDGE_COUNT;
};
@ -221,9 +222,18 @@ _hb_ft_paint (hb_ft_paint_context_t *c,
&paint.u.colr_layers.layer_iterator,
&other_paint))
{
unsigned i = paint.u.colr_layers.layer_iterator.layer;
if (unlikely (c->current_layers.has (i)))
continue;
c->current_layers.add (i);
c->funcs->push_group (c->data);
c->recurse (other_paint);
c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER);
c->current_layers.del (i);
}
}
break;