[subset] fix a class of fuzzer timeouts caused by large shared coverage tables.

More acurately estimates the op count for CoverageFormat2 tables as the population size instead of the size in bytes.
This commit is contained in:
Garret Rieger 2023-02-22 23:11:29 +00:00
parent ddd0f7f40b
commit 918193ebf9
4 changed files with 22 additions and 2 deletions

View File

@ -28,7 +28,13 @@ struct SinglePosFormat1
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
coverage.sanitize (c, this) &&
valueFormat.sanitize_value (c, this, values));
valueFormat.sanitize_value (c, this, values) &&
// The coverage table may use a range to represent a set
// of glyphs, which means a small number of bytes can
// generate a large glyph set. Manually modify the
// sanitizer max ops to take this into account.
c->check_ops ((this + coverage).get_population () >> 1));
}
bool intersects (const hb_set_t *glyphs) const

View File

@ -25,7 +25,13 @@ struct SingleSubstFormat1_3
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (coverage.sanitize (c, this) && deltaGlyphID.sanitize (c));
return_trace (coverage.sanitize (c, this) &&
deltaGlyphID.sanitize (c) &&
// The coverage table may use a range to represent a set
// of glyphs, which means a small number of bytes can
// generate a large glyph set. Manually modify the
// sanitizer max ops to take this into account.
c->check_ops ((this + coverage).get_population () >> 1));
}
hb_codepoint_t get_mask () const

View File

@ -228,6 +228,14 @@ struct hb_sanitize_context_t :
unsigned get_edit_count () { return edit_count; }
bool check_ops(int count)
{
// Manually decrements the ops counter. Used when the automatic op
// counting needs adjustment.
return (this->max_ops -= count) > 0;
}
bool check_range (const void *base,
unsigned int len) const
{