[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.
This commit is contained in:
Werner Lemberg 2009-06-28 01:25:55 +02:00
parent 6bb34880e8
commit e7389a4405
5 changed files with 42 additions and 6 deletions

View File

@ -1,3 +1,14 @@
2009-06-28 Werner Lemberg <wl@gnu.org>
[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 <wl@gnu.org>
Thinko.

View File

@ -692,6 +692,8 @@ FT_BEGIN_HEADER
FT_Int* buildchar;
FT_UInt len_buildchar;
FT_Bool seac;
} T1_DecoderRec;

View File

@ -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;
}

View File

@ -154,6 +154,8 @@ FT_BEGIN_HEADER
FT_Render_Mode hint_mode;
FT_Bool seac;
} CFF_Decoder;

View File

@ -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" ));