diff --git a/ChangeLog b/ChangeLog index 5f2fb9731..ac063f1a6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2018-09-12 Werner Lemberg + + * src/truetype/ttgxvar.c (ft_var_load_gvar): Check `glyphoffsets'. + 2018-09-10 Armin Hasitzka * src/pshinter/pshrec.c (t2_hints_stems): Mask numeric overflow. diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c index fef0c8a46..3a2c5409d 100644 --- a/src/truetype/ttgxvar.c +++ b/src/truetype/ttgxvar.c @@ -1531,24 +1531,51 @@ if ( gvar_head.flags & 1 ) { + FT_ULong limit = gvar_start + table_len; + + /* long offsets (one more offset than glyphs, to mark size of last) */ if ( FT_FRAME_ENTER( ( blend->gv_glyphcnt + 1 ) * 4L ) ) goto Exit; for ( i = 0; i <= blend->gv_glyphcnt; i++ ) + { blend->glyphoffsets[i] = offsetToData + FT_GET_ULONG(); + /* use `>', not `>=' */ + if ( blend->glyphoffsets[i] > limit ) + { + FT_TRACE2(( "ft_var_load_gvar:" + " invalid glyph variation data offset for index %d\n", + i )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + } FT_FRAME_EXIT(); } else { + FT_ULong limit = gvar_start + table_len; + + /* short offsets (one more offset than glyphs, to mark size of last) */ if ( FT_FRAME_ENTER( ( blend->gv_glyphcnt + 1 ) * 2L ) ) goto Exit; for ( i = 0; i <= blend->gv_glyphcnt; i++ ) + { blend->glyphoffsets[i] = offsetToData + FT_GET_USHORT() * 2; - /* XXX: Undocumented: `*2'! */ + /* use `>', not `>=' */ + if ( blend->glyphoffsets[i] > limit ) + { + FT_TRACE2(( "ft_var_load_gvar:" + " invalid glyph variation data offset for index %d\n", + i )); + error = FT_THROW( Invalid_Table ); + goto Exit; + } + } FT_FRAME_EXIT(); }