Commit 29e044a4af2f63bbebadf0d23d14be6ec4af86ec

suzuki toshiya 2010-08-31T01:23:30

[truetype] Prevent bytecode reuse after the interpretation error. * src/truetype/ttinterp.c (free_buffer_in_size): New function to free the buffer allocated during the interpretation of this glyph. (TT_RunIns): Unset FT_Face->size->{cvt_ready,bytecode_ready} if an error occurs in the bytecode interpretation. The interpretation of invalid bytecode may break the function definitions and referring them in later interpretation is danger. By unsetting these flags, `fpgm' and `prep' tables are executed again in next interpretation. Fix Savannah bug #30798, reported by Robert Swiecki.

diff --git a/ChangeLog b/ChangeLog
index bf15e12..f0e03d8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2010-08-30  suzuki toshiya  <mpsuzuki@hiroshima-u.ac.jp>
+
+	[truetype] Prevent bytecode reuse after the interpretation error.
+
+	* src/truetype/ttinterp.c (free_buffer_in_size): New function to
+	free the buffer allocated during the interpretation of this glyph.
+	(TT_RunIns): Unset FT_Face->size->{cvt_ready,bytecode_ready} if
+	an error occurs in the bytecode interpretation.  The interpretation
+	of invalid bytecode may break the function definitions and referring
+	them in later interpretation is danger.  By unsetting these flags,
+	`fpgm' and `prep' tables are executed again in next interpretation.
+
+	Fix Savannah bug #30798, reported by Robert Swiecki.
+
 2010-08-29  Werner Lemberg  <wl@gnu.org>
 
 	[ftraster] Pacify compiler.
diff --git a/src/truetype/ttinterp.c b/src/truetype/ttinterp.c
index d22e94f..e38d3a8 100644
--- a/src/truetype/ttinterp.c
+++ b/src/truetype/ttinterp.c
@@ -7362,6 +7362,41 @@
 #endif /* !TT_CONFIG_OPTION_INTERPRETER_SWITCH */
 
 
+  static void
+  free_buffer_in_size( TT_ExecContext  exc )
+  {
+    FT_Memory        memory = exc->memory;
+    TT_Size          size = exc->size;
+    TT_GlyphZoneRec  twilight;
+
+
+    if ( !size )
+      return;
+
+    if ( size->function_defs )
+      FT_FREE( size->function_defs );
+    if ( size->instruction_defs )
+      FT_FREE( size->instruction_defs );
+    if ( size->cvt )
+      FT_FREE( size->cvt );
+    if ( size->storage )
+      FT_FREE( size->storage );
+
+    twilight = size->twilight;
+
+    if ( twilight.org )
+      FT_FREE( twilight.org );
+    if ( twilight.cur )
+      FT_FREE( twilight.cur );
+    if ( twilight.orus )
+      FT_FREE( twilight.orus );
+    if ( twilight.tags )
+      FT_FREE( twilight.tags );
+    if ( twilight.contours )
+      FT_FREE( twilight.contours );
+  }
+
+
   /*************************************************************************/
   /*                                                                       */
   /* RUN                                                                   */
@@ -8128,6 +8163,16 @@
     *exc = cur;
 #endif
 
+    /* if any errors, function tables may be broken.  */
+    /* it should not be used for next interpretation. */
+    if ( CUR.error )
+    {
+      FT_TRACE7(( "  The interpreter got an error = %d\n", CUR.error ));
+      free_buffer_in_size( exc );
+      exc->size->cvt_ready = FALSE;  
+      exc->size->bytecode_ready = FALSE;  
+    }
+
     return CUR.error;
   }