diff --git a/ChangeLog b/ChangeLog index 6c62411c1..df11d1bf4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2009-06-28 Werner Lemberg + + [psaux, cff] Protect against nested `seac' calls. + + * include/freetype/internal/psaux.h (T1_Decoder), src/cff/cffgload.h + (CFF_Decoder): Add `seac' boolean variable. + + * src/cff/cffgload.c (cff_operator_seac, + cff_decoder_parse_charstrings), src/psaux/t1decode.c + (t1operator_seac, t1_decoder_parse_charstrings): Use it. + 2009-06-28 Werner Lemberg Thinko. diff --git a/include/freetype/internal/psaux.h b/include/freetype/internal/psaux.h index cac9f47a7..503eb2b4d 100644 --- a/include/freetype/internal/psaux.h +++ b/include/freetype/internal/psaux.h @@ -692,6 +692,8 @@ FT_BEGIN_HEADER FT_Int* buildchar; FT_UInt len_buildchar; + FT_Bool seac; + } T1_DecoderRec; diff --git a/src/cff/cffgload.c b/src/cff/cffgload.c index d21631288..2a982f40a 100644 --- a/src/cff/cffgload.c +++ b/src/cff/cffgload.c @@ -707,6 +707,12 @@ FT_ULong charstring_len; + if ( decoder->seac ) + { + FT_ERROR(( "cff_operator_seac: invalid nested seac\n" )); + return CFF_Err_Syntax_Error; + } + #ifdef FT_CONFIG_OPTION_INCREMENTAL /* Incremental fonts don't necessarily have valid charsets. */ /* They use the character code, not the glyph index, in this case. */ @@ -1883,11 +1889,14 @@ FT_Pos glyph_width = decoder->glyph_width; + /* the seac operator must not be nested */ + decoder->seac = TRUE; error = cff_operator_seac( decoder, args[-4], args[-3], (FT_Int)( args[-2] >> 16 ), (FT_Int)( args[-1] >> 16 ) ); + decoder->seac = FALSE; decoder->glyph_width = glyph_width; } diff --git a/src/cff/cffgload.h b/src/cff/cffgload.h index ff28670dc..956817a08 100644 --- a/src/cff/cffgload.h +++ b/src/cff/cffgload.h @@ -154,6 +154,8 @@ FT_BEGIN_HEADER FT_Render_Mode hint_mode; + FT_Bool seac; + } CFF_Decoder; diff --git a/src/psaux/t1decode.c b/src/psaux/t1decode.c index fcd7d57de..39b5c8b96 100644 --- a/src/psaux/t1decode.c +++ b/src/psaux/t1decode.c @@ -198,6 +198,13 @@ T1_Face face = (T1_Face)decoder->builder.face; #endif + + if ( decoder->seac ) + { + FT_ERROR(( "t1operator_seac: invalid nested seac\n" )); + return PSaux_Err_Syntax_Error; + } + /* seac weirdness */ adx += decoder->builder.left_bearing.x; @@ -1118,13 +1125,18 @@ break; case op_seac: + /* the seac operator must not be nested */ + decoder->seac = TRUE; + error = t1operator_seac( decoder, + top[0], + top[1], + top[2], + (FT_Int)( top[3] >> 16 ), + (FT_Int)( top[4] >> 16 ) ); + decoder->seac = FALSE; + /* return immediately after the processing */ - return t1operator_seac( decoder, - top[0], - top[1], - top[2], - (FT_Int)( top[3] >> 16 ), - (FT_Int)( top[4] >> 16 ) ); + return error; case op_sbw: FT_TRACE4(( " sbw" ));