From 257d1adfa1b3422c511c55e641840a6e31ec6008 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 4 Jun 2014 18:47:55 -0400 Subject: [PATCH] [ot-font] Work around broken cmap subtable format 4 length Roboto was hitting this. FreeType also has pretty much the same code for this, in ttcmap.c:tt_cmap4_validate(): /* in certain fonts, the `length' field is invalid and goes */ /* out of bound. We try to correct this here... */ if ( table + length > valid->limit ) { if ( valid->level >= FT_VALIDATE_TIGHT ) FT_INVALID_TOO_SHORT; length = (FT_UInt)( valid->limit - table ); } --- src/hb-ot-cmap-table.hh | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index abaceaad..65434c40 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: -- GitLab