Commit 6da023d1ff9b70f78c900774cc5d362af53ad92c

Werner Lemberg 2010-05-20T15:38:00

TrueType: Make FreeType ignore maxSizeOfInstructions in `maxp'. Acroread does the same. * src/truetype/ttgload.c (TT_Process_Composite_Glyph): Call `Update_Max' to adjust size of instructions array if necessary and add a rough safety check. (load_truetype_glyph): Save `loader->byte_len' before recursive call. * src/truetype/ttinterp.h, src/truetype/ttinterp.c (Update_Max): Declare it as FT_LOCAL.

diff --git a/ChangeLog b/ChangeLog
index 7bb5fc1..5887202 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2010-05-20  Werner Lemberg  <wl@gnu.org>
+
+	TrueType: Make FreeType ignore maxSizeOfInstructions in `maxp'.
+
+	Acroread does the same.
+
+	* src/truetype/ttgload.c (TT_Process_Composite_Glyph): Call
+	`Update_Max' to adjust size of instructions array if necessary and
+	add a rough safety check.
+
+	(load_truetype_glyph): Save `loader->byte_len' before recursive
+	call.
+
+	* src/truetype/ttinterp.h, src/truetype/ttinterp.c (Update_Max):
+	Declare it as FT_LOCAL.
+
 2010-05-18  Hongbo Ni  <hongbo@njstar.com>
 
 	Apply patch #7196.
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
index ad416f0..2fc031b 100644
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -1141,7 +1141,8 @@
 
     {
       FT_Stream  stream = loader->stream;
-      FT_UShort  n_ins;
+      FT_UShort  n_ins, max_ins;
+      FT_ULong   tmp;
 
 
       /* TT_Load_Composite_Glyph only gives us the offset of instructions */
@@ -1153,12 +1154,27 @@
       FT_TRACE5(( "  Instructions size = %d\n", n_ins ));
 
       /* check it */
-      if ( n_ins > ((TT_Face)loader->face)->max_profile.maxSizeOfInstructions )
+      max_ins = ((TT_Face)loader->face)->max_profile.maxSizeOfInstructions;
+      if ( n_ins > max_ins )
       {
-        FT_TRACE0(( "TT_Process_Composite_Glyph: too many instructions (%d)\n",
-                    n_ins ));
+        /* acroread ignores this field, so we only do a rough safety check */
+        if ( (FT_Int)n_ins > loader->byte_len )
+        {
+          FT_TRACE1(( "TT_Process_Composite_Glyph: "
+                      "too many instructions (%d) for glyph with length (%d)\n",
+                      n_ins, loader->byte_len ));
+          return TT_Err_Too_Many_Hints;
+        }
 
-        return TT_Err_Too_Many_Hints;
+        tmp = loader->exec->glyphSize;
+        error = Update_Max( loader->exec->memory,
+                            &tmp,
+                            sizeof ( FT_Byte ),
+                            (void*)&loader->exec->glyphIns,
+                            n_ins );
+        loader->exec->glyphSize = (FT_UShort)tmp;
+        if ( error )
+          return error;
       }
       else if ( n_ins == 0 )
         return TT_Err_Ok;
@@ -1516,6 +1532,7 @@
         FT_UInt      num_base_subgs = gloader->base.num_subglyphs;
 
         FT_Stream    old_stream     = loader->stream;
+        FT_Int       old_byte_len   = loader->byte_len;
 
 
         FT_GlyphLoader_Add( gloader );
@@ -1570,7 +1587,8 @@
                                           num_base_points );
         }
 
-        loader->stream = old_stream;
+        loader->stream   = old_stream;
+        loader->byte_len = old_byte_len;
 
         /* process the glyph */
         loader->ins_pos = ins_pos;
diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c
index 13aa9a2..18ff7c6 100644
--- a/src/truetype/ttinterp.c
+++ b/src/truetype/ttinterp.c
@@ -4,8 +4,9 @@
 /*                                                                         */
 /*    TrueType bytecode interpreter (body).                                */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */
-/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,   */
+/*            2010                                                         */
+/*  by David Turner, Robert Wilhelm, and Werner Lemberg.                   */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
 /*  modified, and distributed under the terms of the FreeType project      */
@@ -508,7 +509,7 @@
   /* <Return>                                                              */
   /*    FreeType error code.  0 means success.                             */
   /*                                                                       */
-  static FT_Error
+  FT_LOCAL_DEF( FT_Error )
   Update_Max( FT_Memory  memory,
               FT_ULong*  size,
               FT_Long    multiplier,
diff --git a/src/truetype/ttinterp.h b/src/truetype/ttinterp.h
index 07a8972..732a1f2 100644
--- a/src/truetype/ttinterp.h
+++ b/src/truetype/ttinterp.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    TrueType bytecode interpreter (specification).                       */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by             */
+/*  Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2010 by       */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -239,6 +239,14 @@ FT_BEGIN_HEADER
                       FT_Int          range );
 
 
+  FT_LOCAL( FT_Error )
+  Update_Max( FT_Memory  memory,
+              FT_ULong*  size,
+              FT_Long    multiplier,
+              void*      _pbuff,
+              FT_ULong   new_max );
+
+
   /*************************************************************************/
   /*                                                                       */
   /* <Function>                                                            */