Limit OT::Lookup subtables (#2219)

Fixes https://crbug.com/oss-fuzz/13943
This commit is contained in:
Ebrahim Byagowi 2020-03-02 22:41:08 +03:30 committed by GitHub
parent 29efd964f2
commit d383603976
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 16 additions and 4 deletions

View File

@ -1097,6 +1097,10 @@ struct Lookup
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
if (!(c->check_struct (this) && subTable.sanitize (c))) return_trace (false); if (!(c->check_struct (this) && subTable.sanitize (c))) return_trace (false);
unsigned subtables = get_subtable_count ();
if (unlikely (!c->visit_subtables (subtables))) return_trace (false);
if (lookupFlag & LookupFlag::UseMarkFilteringSet) if (lookupFlag & LookupFlag::UseMarkFilteringSet)
{ {
const HBUINT16 &markFilteringSet = StructAfter<HBUINT16> (subTable); const HBUINT16 &markFilteringSet = StructAfter<HBUINT16> (subTable);
@ -1119,8 +1123,7 @@ struct Lookup
* https://bugs.chromium.org/p/chromium/issues/detail?id=960331 * https://bugs.chromium.org/p/chromium/issues/detail?id=960331
*/ */
unsigned int type = get_subtable<TSubTable> (0).u.extension.get_type (); unsigned int type = get_subtable<TSubTable> (0).u.extension.get_type ();
unsigned int count = get_subtable_count (); for (unsigned int i = 1; i < subtables; i++)
for (unsigned int i = 1; i < count; i++)
if (get_subtable<TSubTable> (i).u.extension.get_type () != type) if (get_subtable<TSubTable> (i).u.extension.get_type () != type)
return_trace (false); return_trace (false);
} }

View File

@ -113,6 +113,9 @@
#ifndef HB_SANITIZE_MAX_OPS_MAX #ifndef HB_SANITIZE_MAX_OPS_MAX
#define HB_SANITIZE_MAX_OPS_MAX 0x3FFFFFFF #define HB_SANITIZE_MAX_OPS_MAX 0x3FFFFFFF
#endif #endif
#ifndef HB_SANITIZE_MAX_SUTABLES
#define HB_SANITIZE_MAX_SUTABLES 0x4000
#endif
struct hb_sanitize_context_t : struct hb_sanitize_context_t :
hb_dispatch_context_t<hb_sanitize_context_t, bool, HB_DEBUG_SANITIZE> hb_dispatch_context_t<hb_sanitize_context_t, bool, HB_DEBUG_SANITIZE>
@ -120,7 +123,7 @@ struct hb_sanitize_context_t :
hb_sanitize_context_t () : hb_sanitize_context_t () :
debug_depth (0), debug_depth (0),
start (nullptr), end (nullptr), start (nullptr), end (nullptr),
max_ops (0), max_ops (0), max_subtables (0),
writable (false), edit_count (0), writable (false), edit_count (0),
blob (nullptr), blob (nullptr),
num_glyphs (65536), num_glyphs (65536),
@ -134,6 +137,12 @@ struct hb_sanitize_context_t :
static return_t no_dispatch_return_value () { return false; } static return_t no_dispatch_return_value () { return false; }
bool stop_sublookup_iteration (const return_t r) const { return !r; } bool stop_sublookup_iteration (const return_t r) const { return !r; }
bool visit_subtables (unsigned count)
{
max_subtables += count;
return max_subtables < HB_SANITIZE_MAX_SUTABLES;
}
private: private:
template <typename T, typename ...Ts> auto template <typename T, typename ...Ts> auto
_dispatch (const T &obj, hb_priority<1>, Ts&&... ds) HB_AUTO_RETURN _dispatch (const T &obj, hb_priority<1>, Ts&&... ds) HB_AUTO_RETURN
@ -380,7 +389,7 @@ struct hb_sanitize_context_t :
mutable unsigned int debug_depth; mutable unsigned int debug_depth;
const char *start, *end; const char *start, *end;
mutable int max_ops; mutable int max_ops, max_subtables;
private: private:
bool writable; bool writable;
unsigned int edit_count; unsigned int edit_count;