diff options
author | Ben Wagner <bungeman@google.com> | 2020-02-29 20:18:00 +0100 |
---|---|---|
committer | Werner Lemberg <wl@gnu.org> | 2020-02-29 20:29:14 +0100 |
commit | 11975fe9f6ed92b7630698e599b936a0186d965d (patch) | |
tree | dde1eee4d075b2b989578a717fb54746d94c9cc2 | |
parent | 149b9055e61d9c46937d3b0cc5727e75484ed042 (diff) | |
download | freetype2-11975fe9f6ed92b7630698e599b936a0186d965d.tar.gz |
Fix state of `FT_Face' for buggy `gvar' tables (#57923).
By resetting the blend as implemented with this commit fonts with
invalid `gvar' tables may keep calling into `ft_var_load_gvar' from
`tt_set_mm_blend' and failing, but the font was invalid anyway and
we want to keep seeing the failure in `tt_set_mm_blend'.
* src/truetype/ttgxvar.c (ft_var_load_gvar): Calculate length of
offset array once.
Allocate arrays after `FT_FRAME_ENTER' (extra check before
allocating and avoid needing to free array later if error entering
frame).
Always call `FT_FRAME_EXIT'.
Consistently set counts immediately after array initialized.
Reset the blend (particularly `blend->glyphoffsets') on failure.
-rw-r--r-- | ChangeLog | 18 | ||||
-rw-r--r-- | src/truetype/ttgxvar.c | 49 |
2 files changed, 46 insertions, 21 deletions
@@ -1,3 +1,21 @@ +2020-02-29 Ben Wagner <bungeman@google.com> + + [truetype] Fix state of `FT_Face' for buggy `gvar' tables (#57923). + + By resetting the blend as implemented with this commit fonts with + invalid `gvar' tables may keep calling into `ft_var_load_gvar' from + `tt_set_mm_blend' and failing, but the font was invalid anyway and + we want to keep seeing the failure in `tt_set_mm_blend'. + + * src/truetype/ttgxvar.c (ft_var_load_gvar): Calculate length of + offset array once. + Allocate arrays after `FT_FRAME_ENTER' (extra check before + allocating and avoid needing to free array later if error entering + frame). + Always call `FT_FRAME_EXIT'. + Consistently set counts immediately after array initialized. + Reset the blend (particularly `blend->glyphoffsets') on failure. + 2020-03-01 Nikhil Ramakrishnan <ramakrishnan.nikhil@gmail.com> [docs] Update docwriter stylesheet. diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c index ce6b62e1f..110f24a11 100644 --- a/src/truetype/ttgxvar.c +++ b/src/truetype/ttgxvar.c @@ -1470,6 +1470,7 @@ FT_ULong table_len; FT_ULong gvar_start; FT_ULong offsetToData; + FT_ULong offsets_len; GX_GVar_Head gvar_head; static const FT_Frame_Field gvar_fields[] = @@ -1530,9 +1531,13 @@ goto Exit; } - /* rough sanity check: offsets can be either 2 or 4 bytes */ - if ( (FT_ULong)gvar_head.glyphCount * - ( ( gvar_head.flags & 1 ) ? 4 : 2 ) > table_len ) + /* offsets can be either 2 or 4 bytes */ + /* (one more offset than glyphs, to mark size of last) */ + offsets_len = ( gvar_head.glyphCount + 1 ) * + ( ( gvar_head.flags & 1 ) ? 4L : 2L ); + + /* rough sanity check */ + if (offsets_len > table_len ) { FT_TRACE1(( "ft_var_load_gvar: invalid number of glyphs\n" )); error = FT_THROW( Invalid_Table ); @@ -1549,19 +1554,19 @@ gvar_head.globalCoordCount, gvar_head.globalCoordCount == 1 ? "" : "s" )); - if ( FT_NEW_ARRAY( blend->glyphoffsets, gvar_head.glyphCount + 1 ) ) + if ( FT_FRAME_ENTER( offsets_len ) ) goto Exit; + /* offsets (one more offset than glyphs, to mark size of last) */ + if ( FT_NEW_ARRAY( blend->glyphoffsets, gvar_head.glyphCount + 1 ) ) + goto Fail2; + if ( gvar_head.flags & 1 ) { FT_ULong limit = gvar_start + table_len; FT_ULong max_offset = 0; - /* long offsets (one more offset than glyphs, to mark size of last) */ - if ( FT_FRAME_ENTER( ( gvar_head.glyphCount + 1 ) * 4L ) ) - goto Exit; - for ( i = 0; i <= gvar_head.glyphCount; i++ ) { blend->glyphoffsets[i] = offsetToData + FT_GET_ULONG(); @@ -1592,10 +1597,6 @@ FT_ULong max_offset = 0; - /* short offsets (one more offset than glyphs, to mark size of last) */ - if ( FT_FRAME_ENTER( ( gvar_head.glyphCount + 1 ) * 2L ) ) - goto Exit; - for ( i = 0; i <= gvar_head.glyphCount; i++ ) { blend->glyphoffsets[i] = offsetToData + FT_GET_USHORT() * 2; @@ -1621,12 +1622,10 @@ } } - FT_FRAME_EXIT(); - if ( error ) - goto Exit; - blend->gv_glyphcnt = gvar_head.glyphCount; + FT_FRAME_EXIT(); + if ( gvar_head.globalCoordCount != 0 ) { if ( FT_STREAM_SEEK( gvar_start + gvar_head.offsetToCoord ) || @@ -1635,16 +1634,14 @@ { FT_TRACE2(( "ft_var_load_gvar:" " glyph variation shared tuples missing\n" )); - goto Exit; + goto Fail; } if ( FT_NEW_ARRAY( blend->tuplecoords, gvar_head.axisCount * gvar_head.globalCoordCount ) ) - goto Exit; - - blend->tuplecount = gvar_head.globalCoordCount; + goto Fail2; - for ( i = 0; i < blend->tuplecount; i++ ) + for ( i = 0; i < gvar_head.globalCoordCount; i++ ) { FT_TRACE5(( " [ " )); for ( j = 0; j < (FT_UInt)gvar_head.axisCount; j++ ) @@ -1657,6 +1654,8 @@ FT_TRACE5(( "]\n" )); } + blend->tuplecount = gvar_head.globalCoordCount; + FT_TRACE5(( "\n" )); FT_FRAME_EXIT(); @@ -1664,6 +1663,14 @@ Exit: return error; + + Fail2: + FT_FRAME_EXIT(); + + Fail: + FT_FREE( blend->glyphoffsets ); + blend->gv_glyphcnt = 0; + goto Exit; } |