diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index abaceaadf1386d9973ea12aced12d27a008e1dd5..65434c4067876cc9011f4c442953569382213b32 100644 --- a/src/hb-ot-cmap-table.hh +++ b/src/hb-ot-cmap-table.hh @@ -131,11 +131,25 @@ struct CmapSubtableFormat4 return true; } - inline bool sanitize (hb_sanitize_context_t *c) { + inline bool sanitize (hb_sanitize_context_t *c) + { TRACE_SANITIZE (this); - return TRACE_RETURN (c->check_struct (this) && - c->check_range (this, length) && - 16 + 4 * (unsigned int) segCountX2 < length); + if (unlikely (!c->check_struct (this))) + return TRACE_RETURN (false); + + if (unlikely (!c->check_range (this, length))) + { + /* Some broken fonts have too long of a "length" value. + * If that is the case, just change the value to truncate + * the subtable at the end of the blob. */ + uint16_t new_length = (uint16_t) MIN ((uintptr_t) 65535, + (uintptr_t) (c->end - + (char *) this)); + if (!c->try_set (&length, new_length)) + return TRACE_RETURN (false); + } + + return TRACE_RETURN (16 + 4 * (unsigned int) segCountX2 <= length); } protected: