diff --git a/ChangeLog b/ChangeLog index 3376a2449..9b9d822d2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2016-12-17 Werner Lemberg + + [sfnt, truetype] Various sanitizing fixes. + + * src/sfnt/sfobjs.c (sfnt_init_face): If the axis count in `fvar' is + zero, set `num_instances' to zero. + + * src/truetype/ttgxvar.c (TT_Get_MM_Var): Handle `fvar' table with + zero axes as invalid. + + * src/truetype/ttobjs.c (tt_face_init): Improve logic of loading + `loca', `cvt', `fpgm', and `prep' table. + 2016-12-17 Werner Lemberg Improve tracing of `FT_Open_Face'. diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c index b3b976127..efda0c102 100644 --- a/src/sfnt/sfobjs.c +++ b/src/sfnt/sfobjs.c @@ -967,6 +967,7 @@ /* based on similar code in function `TT_Get_MM_Var' */ if ( version != 0x00010000UL || axis_size != 20 || + num_axes == 0 || num_axes > 0x3FFE || instance_size != 4 + 4 * num_axes || num_instances > 0x7EFF || diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c index 12a316036..8746b25f5 100644 --- a/src/truetype/ttgxvar.c +++ b/src/truetype/ttgxvar.c @@ -1355,6 +1355,7 @@ fvar_head.countSizePairs != 2 || #endif fvar_head.axisSize != 20 || + fvar_head.axisCount == 0 || /* axisCount limit implied by 16-bit instanceSize */ fvar_head.axisCount > 0x3FFE || fvar_head.instanceCount > 0x7EFF || diff --git a/src/truetype/ttobjs.c b/src/truetype/ttobjs.c index 758eaeb44..81577a49b 100644 --- a/src/truetype/ttobjs.c +++ b/src/truetype/ttobjs.c @@ -581,13 +581,29 @@ #ifdef FT_CONFIG_OPTION_INCREMENTAL if ( !ttface->internal->incremental_interface ) + { error = tt_face_load_loca( face, stream ); - if ( !error ) - error = tt_face_load_cvt( face, stream ); - if ( !error ) - error = tt_face_load_fpgm( face, stream ); - if ( !error ) - error = tt_face_load_prep( face, stream ); + + /* having a (non-zero) `glyf' table without */ + /* a `loca' table is not valid */ + if ( face->glyf_len && FT_ERR_EQ( error, Table_Missing ) ) + goto Exit; + if ( error ) + goto Exit; + } + + /* `fpgm', `cvt', and `prep' are optional */ + error = tt_face_load_cvt( face, stream ); + if ( error && FT_ERR_NEQ( error, Table_Missing ) ) + goto Exit; + + error = tt_face_load_fpgm( face, stream ); + if ( error && FT_ERR_NEQ( error, Table_Missing ) ) + goto Exit; + + error = tt_face_load_prep( face, stream ); + if ( error && FT_ERR_NEQ( error, Table_Missing ) ) + goto Exit; /* Check the scalable flag based on `loca'. */ if ( !ttface->internal->incremental_interface && @@ -605,14 +621,27 @@ #else /* !FT_CONFIG_OPTION_INCREMENTAL */ - if ( !error ) - error = tt_face_load_loca( face, stream ); - if ( !error ) - error = tt_face_load_cvt( face, stream ); - if ( !error ) - error = tt_face_load_fpgm( face, stream ); - if ( !error ) - error = tt_face_load_prep( face, stream ); + error = tt_face_load_loca( face, stream ); + + /* having a (non-zero) `glyf' table without */ + /* a `loca' table is not valid */ + if ( face->glyf_len && FT_ERR_EQ( error, Table_Missing ) ) + goto Exit; + if ( error ) + goto Exit; + + /* `fpgm', `cvt', and `prep' are optional */ + error = tt_face_load_cvt( face, stream ); + if ( error && FT_ERR_NEQ( error, Table_Missing ) ) + goto Exit; + + error = tt_face_load_fpgm( face, stream ); + if ( error && FT_ERR_NEQ( error, Table_Missing ) ) + goto Exit; + + error = tt_face_load_prep( face, stream ); + if ( error && FT_ERR_NEQ( error, Table_Missing ) ) + goto Exit; /* Check the scalable flag based on `loca'. */ if ( ttface->num_fixed_sizes && diff --git a/src/truetype/ttpload.c b/src/truetype/ttpload.c index cd1d27c0d..0079ebd05 100644 --- a/src/truetype/ttpload.c +++ b/src/truetype/ttpload.c @@ -89,7 +89,6 @@ face->glyf_offset = FT_STREAM_POS(); } - FT_TRACE2(( "Locations " )); error = face->goto_table( face, TTAG_loca, stream, &table_len ); if ( error )