[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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122
diff --git a/ChangeLog b/ChangeLog
index 6c62411..df11d1b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
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.
* src/psaux/t1decode.c (t1operator_seac)
diff --git a/include/freetype/internal/psaux.h b/include/freetype/internal/psaux.h
index cac9f47..503eb2b 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 d216312..2a982f4 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 ff28670..956817a 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 fcd7d57..39b5c8b 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" ));