From e7389a4405223c40e552122451c7612ae030c20d Mon Sep 17 00:00:00 2001
From: Werner Lemberg <wl@gnu.org>
Date: Sat, 27 Jun 2009 23:25:55 +0000
Subject: [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.

From 24370d67f59a81b4fbc802a8a2abe3ae3e8b0c8b Mon Sep 17 00:00:00 2001
From: Werner Lemberg <wl@gnu.org>
Date: Sun, 28 Jun 2009 00:11:51 +0000
Subject: Uff, another thinko.

Description: fix denial of service via nested "seac" calls
Origin: upstream, http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=e7389a4405223c40e552122451c7612ae030c20d
Origin: upstream, http://git.savannah.gnu.org/cgit/freetype/freetype2.git/commit/?id=24370d67f59a81b4fbc802a8a2abe3ae3e8b0c8b

Index: freetype-2.3.7/include/freetype/internal/psaux.h
===================================================================
--- freetype-2.3.7.orig/include/freetype/internal/psaux.h
+++ freetype-2.3.7/include/freetype/internal/psaux.h
@@ -692,6 +692,8 @@ FT_BEGIN_HEADER
     FT_Int*              buildchar;
     FT_UInt              len_buildchar;
 
+    FT_Bool              seac;
+
   } T1_DecoderRec;
 
 
Index: freetype-2.3.7/src/cff/cffgload.c
===================================================================
--- freetype-2.3.7.orig/src/cff/cffgload.c
+++ freetype-2.3.7/src/cff/cffgload.c
@@ -688,6 +688,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. */
@@ -758,8 +764,11 @@
                                 &charstring, &charstring_len );
     if ( !error )
     {
+      /* the seac operator must not be nested */
+      decoder->seac = TRUE;
       error = cff_decoder_parse_charstrings( decoder, charstring,
                                              charstring_len );
+      decoder->seac = FALSE;
 
       if ( error )
         goto Exit;
@@ -784,8 +793,11 @@
                                 &charstring, &charstring_len );
     if ( !error )
     {
+      /* the seac operator must not be nested */
+      decoder->seac = TRUE;
       error = cff_decoder_parse_charstrings( decoder, charstring,
                                              charstring_len );
+      decoder->seac = FALSE;
 
       if ( error )
         goto Exit;
Index: freetype-2.3.7/src/cff/cffgload.h
===================================================================
--- freetype-2.3.7.orig/src/cff/cffgload.h
+++ freetype-2.3.7/src/cff/cffgload.h
@@ -157,6 +157,8 @@ FT_BEGIN_HEADER
 
     FT_Render_Mode     hint_mode;
 
+    FT_Bool            seac;
+
   } CFF_Decoder;
 
 
Index: freetype-2.3.7/src/psaux/t1decode.c
===================================================================
--- freetype-2.3.7.orig/src/psaux/t1decode.c
+++ freetype-2.3.7/src/psaux/t1decode.c
@@ -194,6 +194,13 @@
     FT_Vector    left_bearing, advance;
 
 
+
+    if ( decoder->seac )
+    {
+      FT_ERROR(( "t1operator_seac: invalid nested seac\n" ));
+      return PSaux_Err_Syntax_Error;
+    }
+
     /* seac weirdness */
     adx += decoder->builder.left_bearing.x;
 
@@ -260,7 +267,10 @@
 
     FT_GlyphLoader_Prepare( decoder->builder.loader );  /* prepare loader */
 
+    /* the seac operator must not be nested */
+    decoder->seac = TRUE;
     error = t1_decoder_parse_glyph( decoder, bchar_index );
+    decoder->seac = FALSE;
     if ( error )
       goto Exit;
 
@@ -278,7 +288,11 @@
 
     /* Now load `achar' on top of */
     /* the base outline           */
+
+    /* the seac operator must not be nested */
+    decoder->seac = TRUE;
     error = t1_decoder_parse_glyph( decoder, achar_index );
+    decoder->seac = FALSE;
     if ( error )
       goto Exit;
 
