diff --git a/src/OT/Layout/GPOS/SinglePosFormat1.hh b/src/OT/Layout/GPOS/SinglePosFormat1.hh index f7a170f34..f379e011a 100644 --- a/src/OT/Layout/GPOS/SinglePosFormat1.hh +++ b/src/OT/Layout/GPOS/SinglePosFormat1.hh @@ -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 diff --git a/src/OT/Layout/GSUB/SingleSubstFormat1.hh b/src/OT/Layout/GSUB/SingleSubstFormat1.hh index 78725352c..c48ff4427 100644 --- a/src/OT/Layout/GSUB/SingleSubstFormat1.hh +++ b/src/OT/Layout/GSUB/SingleSubstFormat1.hh @@ -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 diff --git a/src/hb-sanitize.hh b/src/hb-sanitize.hh index eb907c6b2..6f3db301f 100644 --- a/src/hb-sanitize.hh +++ b/src/hb-sanitize.hh @@ -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 { diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5192684970311680 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5192684970311680 new file mode 100644 index 000000000..0896b6b26 Binary files /dev/null and b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5192684970311680 differ