Commit 470210b73c2afb76a14025b7e89327a74b3f505a

Werner Lemberg 2007-06-06T10:05:49

* src/winfonts/winfnt.c (fnt_face_get_dll_font): Do a rough check of `font_count'. * src/type1/t1load.c (parse_font_matrix): Check `temp_scale'. * src/cff/cffgload.c (cff_decoder_prepare): Change return type to `FT_Error'. Check `fd_index'. (cff_slot_load): Updated. * src/cff/cffgload.h: Updated.

diff --git a/ChangeLog b/ChangeLog
index 2c7e0eb..c26bf5e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -6,6 +6,20 @@
 	* src/pfr/pfrcmap.c (pfr_cmap_init): Convert assertion into normal
 	FreeType error.
 
+
+	* src/winfonts/winfnt.c (fnt_face_get_dll_font): Do a rough check of
+	`font_count'.
+
+
+	* src/type1/t1load.c (parse_font_matrix): Check `temp_scale'.
+
+
+	* src/cff/cffgload.c (cff_decoder_prepare): Change return type to
+	`FT_Error'.
+	Check `fd_index'.
+	(cff_slot_load): Updated.
+	* src/cff/cffgload.h: Updated.
+
 2007-06-05  Werner Lemberg  <wl@gnu.org>
 
 	* src/pfr/pfrgload.c (pfr_glyph_done): Comment out unused code.
@@ -18,7 +32,7 @@
 	* src/pfr/pfrtypes.h (PFR_GlyphRec): Comment out unused code.
 
 
-	* src/winfnt/winfnt.c (FNT_Face_Init): Check `family_size'.
+	* src/winfonts/winfnt.c (FNT_Face_Init): Check `family_size'.
 
 
 	* src/psaux/psobjs.c (ps_tocoordarray, ps_tofixedarray): Return -1
diff --git a/src/cff/cffgload.c b/src/cff/cffgload.c
index 4ec5a81..7d4c49a 100644
--- a/src/cff/cffgload.c
+++ b/src/cff/cffgload.c
@@ -372,12 +372,13 @@
 
 
   /* this function is used to select the locals subrs array */
-  FT_LOCAL_DEF( void )
+  FT_LOCAL_DEF( FT_Error )
   cff_decoder_prepare( CFF_Decoder*  decoder,
                        FT_UInt       glyph_index )
   {
-    CFF_Font     cff = (CFF_Font)decoder->builder.face->extra.data;
-    CFF_SubFont  sub = &cff->top_font;
+    CFF_Font     cff   = (CFF_Font)decoder->builder.face->extra.data;
+    CFF_SubFont  sub   = &cff->top_font;
+    FT_Error     error = CFF_Err_Ok;
 
 
     /* manage CID fonts */
@@ -386,6 +387,13 @@
       FT_Byte  fd_index = cff_fd_select_get( &cff->fd_select, glyph_index );
 
 
+      if ( fd_index > CFF_MAX_CID_FONTS )
+      {
+        FT_TRACE4(( "cff_decoder_prepare: invalid CID subfont index\n" ));
+        error = CFF_Err_Invalid_File_Format;
+        goto Exit;
+      }
+        
       sub = cff->subfonts[fd_index];
     }
 
@@ -395,6 +403,9 @@
 
     decoder->glyph_width   = sub->private_dict.default_width;
     decoder->nominal_width = sub->private_dict.nominal_width;
+
+  Exit:
+    return error;
   }
 
 
@@ -2249,9 +2260,11 @@
                                   &charstring, &charstring_len );
       if ( !error )
       {
-        cff_decoder_prepare( &decoder, glyph_index );
-        error = cff_decoder_parse_charstrings( &decoder,
-                                               charstring, charstring_len );
+        error = cff_decoder_prepare( &decoder, glyph_index );
+        if ( !error )
+          error = cff_decoder_parse_charstrings( &decoder,
+                                                 charstring,
+                                                 charstring_len );
 
         cff_free_glyph_data( face, &charstring, &charstring_len );
       }
@@ -2400,36 +2413,40 @@
                                   &charstring, &charstring_len );
       if ( !error )
       {
-        cff_decoder_prepare( &decoder, glyph_index );
-        error = cff_decoder_parse_charstrings( &decoder,
-                                               charstring, charstring_len );
+        error = cff_decoder_prepare( &decoder, glyph_index );
+        if ( !error )
+        {
+          error = cff_decoder_parse_charstrings( &decoder,
+                                                 charstring,
+                                                 charstring_len );
 
-        cff_free_glyph_data( face, &charstring, charstring_len );
+          cff_free_glyph_data( face, &charstring, charstring_len );
 
 
 #ifdef FT_CONFIG_OPTION_INCREMENTAL
-        /* Control data and length may not be available for incremental   */
-        /* fonts.                                                         */
-        if ( face->root.internal->incremental_interface )
-        {
-          glyph->root.control_data = 0;
-          glyph->root.control_len = 0;
-        }
-        else
+          /* Control data and length may not be available for incremental */
+          /* fonts.                                                       */
+          if ( face->root.internal->incremental_interface )
+          {
+            glyph->root.control_data = 0;
+            glyph->root.control_len = 0;
+          }
+          else
 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
 
-        /* We set control_data and control_len if charstrings is loaded.  */
-        /* See how charstring loads at cff_index_access_element() in      */
-        /* cffload.c.                                                     */
-        {
-          CFF_Index csindex = &cff->charstrings_index;
+          /* We set control_data and control_len if charstrings is loaded. */
+          /* See how charstring loads at cff_index_access_element() in     */
+          /* cffload.c.                                                    */
+          {
+            CFF_Index  csindex = &cff->charstrings_index;
 
 
-          if ( csindex->offsets )
-          {
-            glyph->root.control_data = csindex->bytes +
-                                         csindex->offsets[glyph_index] - 1;
-            glyph->root.control_len  = charstring_len;
+            if ( csindex->offsets )
+            {
+              glyph->root.control_data = csindex->bytes +
+                                           csindex->offsets[glyph_index] - 1;
+              glyph->root.control_len  = charstring_len;
+            }
           }
         }
       }
@@ -2462,25 +2479,27 @@
 
 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
 
-    if ( cff->num_subfonts >= 1 )
+    if ( !error )
     {
-      FT_Byte  fd_index = cff_fd_select_get( &cff->fd_select, glyph_index );
+      if ( cff->num_subfonts >= 1 )
+      {
+        FT_Byte  fd_index = cff_fd_select_get( &cff->fd_select,
+                                               glyph_index );
 
 
-      font_matrix = cff->subfonts[fd_index]->font_dict.font_matrix;
-      font_offset = cff->subfonts[fd_index]->font_dict.font_offset;
-    }
-    else
-    {
-      font_matrix = cff->top_font.font_dict.font_matrix;
-      font_offset = cff->top_font.font_dict.font_offset;
-    }
+        font_matrix = cff->subfonts[fd_index]->font_dict.font_matrix;
+        font_offset = cff->subfonts[fd_index]->font_dict.font_offset;
+      }
+      else
+      {
+        font_matrix = cff->top_font.font_dict.font_matrix;
+        font_offset = cff->top_font.font_dict.font_offset;
+      }
+
+      /* Now, set the metrics -- this is rather simple, as   */
+      /* the left side bearing is the xMin, and the top side */
+      /* bearing the yMax.                                   */
 
-    /* Now, set the metrics -- this is rather simple, as   */
-    /* the left side bearing is the xMin, and the top side */
-    /* bearing the yMax.                                   */
-    if ( !error )
-    {
       /* For composite glyphs, return only left side bearing and */
       /* advance width.                                          */
       if ( load_flags & FT_LOAD_NO_RECURSE )
diff --git a/src/cff/cffgload.h b/src/cff/cffgload.h
index 01c6bcb..f67864a 100644
--- a/src/cff/cffgload.h
+++ b/src/cff/cffgload.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    OpenType Glyph Loader (specification).                               */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2003, 2004, 2006 by                         */
+/*  Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007 by                   */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -175,7 +175,7 @@ FT_BEGIN_HEADER
                     FT_Bool         hinting,
                     FT_Render_Mode  hint_mode );
 
-  FT_LOCAL( void )
+  FT_LOCAL( FT_Error )
   cff_decoder_prepare( CFF_Decoder*  decoder,
                        FT_UInt       glyph_index );
 
diff --git a/src/type1/t1load.c b/src/type1/t1load.c
index 51b0b13..0186dec 100644
--- a/src/type1/t1load.c
+++ b/src/type1/t1load.c
@@ -1079,6 +1079,13 @@
 
     temp_scale = FT_ABS( temp[3] );
 
+    if ( temp_scale == 0 )
+    {
+      FT_ERROR(( "parse_font_matrix: invalid font matrix\n" ));
+      parser->root.error = T1_Err_Invalid_File_Format;
+      return;
+    }
+
     /* Set Units per EM based on FontMatrix values.  We set the value to */
     /* 1000 / temp_scale, because temp_scale was already multiplied by   */
     /* 1000 (in t1_tofixed, from psobjs.c).                              */
diff --git a/src/winfonts/winfnt.c b/src/winfonts/winfnt.c
index 31ae545..9ee9f67 100644
--- a/src/winfonts/winfnt.c
+++ b/src/winfonts/winfnt.c
@@ -267,6 +267,15 @@
           goto Exit;
         }
 
+        /* loading `winfnt_header_fields' needs at least 118 bytes;    */
+        /* use this as a rough measure to check the expected font size */
+        if ( font_count * 118UL > stream->size )
+        {
+          FT_TRACE2(( "invalid number of faces\n" ));
+          error = FNT_Err_Invalid_File_Format;
+          goto Exit;
+        }
+
         face->root.num_faces = font_count;
 
         if ( face_index >= font_count )