diff --git a/ChangeLog b/ChangeLog index f23507aa0..2010fdadf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2014-02-26 Werner Lemberg + + [sfnt] Fix Savannah bug #41696. + + * src/sfnt/ttcmap.c (tt_cmap0_validate, tt_cmap2_validate, + tt_cmap4_validate, tt_cmap14_validate): Fix limit tests. + 2014-02-26 Werner Lemberg [winfnt] Fix Savannah bug #41694. diff --git a/src/sfnt/ttcmap.c b/src/sfnt/ttcmap.c index f17ce59ae..c717f5ffc 100644 --- a/src/sfnt/ttcmap.c +++ b/src/sfnt/ttcmap.c @@ -88,10 +88,16 @@ tt_cmap0_validate( FT_Byte* table, FT_Validator valid ) { - FT_Byte* p = table + 2; - FT_UInt length = TT_NEXT_USHORT( p ); + FT_Byte* p; + FT_UInt length; + if ( table + 2 + 2 > valid->limit ) + FT_INVALID_TOO_SHORT; + + p = table + 2; /* skip format */ + length = TT_NEXT_USHORT( p ); + if ( table + length > valid->limit || length < 262 ) FT_INVALID_TOO_SHORT; @@ -279,13 +285,20 @@ tt_cmap2_validate( FT_Byte* table, FT_Validator valid ) { - FT_Byte* p = table + 2; /* skip format */ - FT_UInt length = TT_PEEK_USHORT( p ); - FT_UInt n, max_subs; - FT_Byte* keys; /* keys table */ - FT_Byte* subs; /* sub-headers */ - FT_Byte* glyph_ids; /* glyph ID array */ + FT_Byte* p; + FT_UInt length; + FT_UInt n, max_subs; + FT_Byte* keys; /* keys table */ + FT_Byte* subs; /* sub-headers */ + FT_Byte* glyph_ids; /* glyph ID array */ + + + if ( table + 2 + 2 > valid->limit ) + FT_INVALID_TOO_SHORT; + + p = table + 2; /* skip format */ + length = TT_NEXT_USHORT( p ); if ( table + length > valid->limit || length < 6 + 512 ) FT_INVALID_TOO_SHORT; @@ -818,13 +831,20 @@ tt_cmap4_validate( FT_Byte* table, FT_Validator valid ) { - FT_Byte* p = table + 2; /* skip format */ - FT_UInt length = TT_NEXT_USHORT( p ); + FT_Byte* p; + FT_UInt length; + FT_Byte *ends, *starts, *offsets, *deltas, *glyph_ids; FT_UInt num_segs; FT_Error error = FT_Err_Ok; + if ( table + 2 + 2 > valid->limit ) + FT_INVALID_TOO_SHORT; + + p = table + 2; /* skip format */ + length = TT_NEXT_USHORT( p ); + if ( length < 16 ) FT_INVALID_TOO_SHORT; @@ -2044,9 +2064,9 @@ tt_cmap12_validate( FT_Byte* table, FT_Validator valid ) { - FT_Byte* p; - FT_ULong length; - FT_ULong num_groups; + FT_Byte* p; + FT_ULong length; + FT_ULong num_groups; if ( table + 16 > valid->limit ) @@ -2754,11 +2774,18 @@ tt_cmap14_validate( FT_Byte* table, FT_Validator valid ) { - FT_Byte* p = table + 2; - FT_ULong length = TT_NEXT_ULONG( p ); - FT_ULong num_selectors = TT_NEXT_ULONG( p ); + FT_Byte* p; + FT_ULong length; + FT_ULong num_selectors; + if ( table + 2 + 4 + 4 > valid->limit ) + FT_INVALID_TOO_SHORT; + + p = table + 2; + length = TT_NEXT_ULONG( p ); + num_selectors = TT_NEXT_ULONG( p ); + if ( length > (FT_ULong)( valid->limit - table ) || length < 10 + 11 * num_selectors ) FT_INVALID_TOO_SHORT;