diff --git a/ChangeLog b/ChangeLog index b95f65e02..0d52a85ab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2015-10-21 Werner Lemberg + + [type42] Better check invalid `sfnts' array data (#46255). + + * src/type42/t42parse.c (t42_parse_sfnts): Table lengths must be + checked individually against available data size. + 2015-10-20 Werner Lemberg [cid] Add a bunch of safety checks. diff --git a/src/type42/t42parse.c b/src/type42/t42parse.c index a32d496af..3bcf97eda 100644 --- a/src/type42/t42parse.c +++ b/src/type42/t42parse.c @@ -575,6 +575,9 @@ while ( parser->root.cursor < limit ) { + FT_ULong size; + + cur = parser->root.cursor; if ( *cur == ']' ) @@ -666,6 +669,11 @@ goto Fail; } + /* The whole TTF is now loaded into `string_buf'. We are */ + /* checking its contents while copying it to `ttf_data'. */ + + size = limit - parser->root.cursor; + for ( n = 0; n < string_size; n++ ) { switch ( status ) @@ -683,7 +691,7 @@ status = BEFORE_TABLE_DIR; face->ttf_size = 12 + 16 * num_tables; - if ( (FT_Long)( limit - parser->root.cursor ) < face->ttf_size ) + if ( (FT_Long)size < face->ttf_size ) { FT_ERROR(( "t42_parse_sfnts: invalid data in sfnts array\n" )); error = FT_THROW( Invalid_File_Format ); @@ -714,6 +722,14 @@ len = FT_PEEK_ULONG( p ); + if ( len > size || + face->ttf_size > (FT_Long)( size - len ) ) + { + FT_ERROR(( "t42_parse_sfnts:" + " invalid data in sfnts array\n" )); + error = FT_THROW( Invalid_File_Format ); + goto Fail; + } /* Pad to a 4-byte boundary length */ face->ttf_size += (FT_Long)( ( len + 3 ) & ~3U ); @@ -721,7 +737,6 @@ status = OTHER_TABLES; - /* there are no more than 256 tables, so no size check here */ if ( FT_REALLOC( face->ttf_data, 12 + 16 * num_tables, face->ttf_size + 1 ) ) goto Fail;