[subset] Fix fuzzer timeout in add_gid_and_children.

The composite glyph graph isn't check for max operations by sanitize so track an operations count during the graph traversal.
This commit is contained in:
Garret Rieger 2021-06-29 16:07:14 -07:00 committed by Behdad Esfahbod
parent c68a00b92e
commit 09474d8d7b
2 changed files with 16 additions and 6 deletions

View File

@ -45,6 +45,10 @@ namespace OT {
*/ */
#define HB_OT_TAG_loca HB_TAG('l','o','c','a') #define HB_OT_TAG_loca HB_TAG('l','o','c','a')
#ifndef HB_MAX_COMPOSITE_OPERATIONS
#define HB_MAX_COMPOSITE_OPERATIONS 1000000
#endif
struct loca struct loca
{ {
@ -1079,18 +1083,24 @@ struct glyf
return needs_padding_removal ? glyph.trim_padding () : glyph; return needs_padding_removal ? glyph.trim_padding () : glyph;
} }
void unsigned
add_gid_and_children (hb_codepoint_t gid, hb_set_t *gids_to_retain, add_gid_and_children (hb_codepoint_t gid,
unsigned int depth = 0) const hb_set_t *gids_to_retain,
unsigned depth = 0,
unsigned operation_count = 0) const
{ {
if (unlikely (depth++ > HB_MAX_NESTING_LEVEL)) return; if (unlikely (depth++ > HB_MAX_NESTING_LEVEL)) return operation_count;
if (unlikely (operation_count++ > HB_MAX_COMPOSITE_OPERATIONS)) return operation_count;
/* Check if is already visited */ /* Check if is already visited */
if (gids_to_retain->has (gid)) return; if (gids_to_retain->has (gid)) return operation_count;
gids_to_retain->add (gid); gids_to_retain->add (gid);
for (auto &item : glyph_for_gid (gid).get_composite_iterator ()) for (auto &item : glyph_for_gid (gid).get_composite_iterator ())
add_gid_and_children (item.get_glyph_index (), gids_to_retain, depth); operation_count +=
add_gid_and_children (item.get_glyph_index (), gids_to_retain, depth, operation_count);
return operation_count;
} }
#ifdef HB_EXPERIMENTAL_API #ifdef HB_EXPERIMENTAL_API