Commit 8b281f83e8516535756f92dbf90940ac44bd45e1

Werner Lemberg 2014-01-23T08:14:53

Fix Savannah bug #41309. * src/type1/t1load.c (t1_parse_font_matrix): Properly handle result of `T1_ToFixedArray'. * src/cid/cidload.c (cid_parse_font_matrix): Synchronize with `t1_parse_font_matrix'. * src/type42/t42parse.c (t42_parse_font_matrix): Synchronize with `t1_parse_font_matrix'. (t42_parse_encoding): Synchronize with `t1_parse_encoding'. * src/psaux/psobjs.c (ps_parser_load_field) <T1_FIELD_TYPE_BBOX>, <T1_FIELD_TYPE_MMOX>: Properly handle result of `ps_tofixedarray'.

diff --git a/ChangeLog b/ChangeLog
index 324ed18..8df8049 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2014-01-23  Werner Lemberg  <wl@gnu.org>
+
+	Fix Savannah bug #41309.
+
+	* src/type1/t1load.c (t1_parse_font_matrix): Properly handle result
+	of `T1_ToFixedArray'.
+
+	* src/cid/cidload.c (cid_parse_font_matrix): Synchronize with
+	`t1_parse_font_matrix'.
+
+	* src/type42/t42parse.c (t42_parse_font_matrix): Synchronize with
+	`t1_parse_font_matrix'.
+	(t42_parse_encoding): Synchronize with `t1_parse_encoding'.
+
+	* src/psaux/psobjs.c (ps_parser_load_field) <T1_FIELD_TYPE_BBOX>,
+	<T1_FIELD_TYPE_MMOX>: Properly handle result of `ps_tofixedarray'.
+
 2014-01-22  Werner Lemberg  <wl@gnu.org>
 
 	* src/autofit/hbshim.c (af_get_coverage): Fix memory leaks.
diff --git a/src/cid/cidload.c b/src/cid/cidload.c
index 46def71..1cda0ee 100644
--- a/src/cid/cidload.c
+++ b/src/cid/cidload.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    CID-keyed Type1 font loader (body).                                  */
 /*                                                                         */
-/*  Copyright 1996-2006, 2009, 2011-2013 by                                */
+/*  Copyright 1996-2006, 2009, 2011-2014 by                                */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -160,16 +160,26 @@
     {
       FT_Matrix*  matrix;
       FT_Vector*  offset;
+      FT_Int      result;
 
 
       dict   = face->cid.font_dicts + parser->num_dict;
       matrix = &dict->font_matrix;
       offset = &dict->font_offset;
 
-      (void)cid_parser_to_fixed_array( parser, 6, temp, 3 );
+      result = cid_parser_to_fixed_array( parser, 6, temp, 3 );
+
+      if ( result < 6 )
+        return FT_THROW( Invalid_File_Format );
 
       temp_scale = FT_ABS( temp[3] );
 
+      if ( temp_scale == 0 )
+      {
+        FT_ERROR(( "cid_parse_font_matrix: invalid font matrix\n" ));
+        return FT_THROW( Invalid_File_Format );
+      }
+
       /* 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).                              */
@@ -184,7 +194,7 @@
         temp[2] = FT_DivFix( temp[2], temp_scale );
         temp[4] = FT_DivFix( temp[4], temp_scale );
         temp[5] = FT_DivFix( temp[5], temp_scale );
-        temp[3] = 0x10000L;
+        temp[3] = temp[3] < 0 ? -0x10000L : 0x10000L;
       }
 
       matrix->xx = temp[0];
@@ -197,8 +207,7 @@
       offset->y  = temp[5] >> 16;
     }
 
-    return FT_Err_Ok;      /* this is a callback function; */
-                            /* we must return an error code */
+    return FT_Err_Ok;
   }
 
 
diff --git a/src/psaux/psobjs.c b/src/psaux/psobjs.c
index dd976d3..b4b7d45 100644
--- a/src/psaux/psobjs.c
+++ b/src/psaux/psobjs.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auxiliary functions for PostScript fonts (body).                     */
 /*                                                                         */
-/*  Copyright 1996-2013 by                                                 */
+/*  Copyright 1996-2014 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -847,6 +847,8 @@
   /* first character must be a delimiter or a part of a number */
   /* NB: `values' can be NULL if we just want to skip the      */
   /*     array; in this case we ignore `max_values'            */
+  /*                                                           */
+  /* return number of successfully parsed values               */
 
   static FT_Int
   ps_tofixedarray( FT_Byte*  *acur,
@@ -1200,7 +1202,7 @@
 
           result = ps_tofixedarray( &cur, limit, 4, temp, 0 );
 
-          if ( result < 0 )
+          if ( result < 4 )
           {
             FT_ERROR(( "ps_parser_load_field:"
                        " expected four integers in bounding box\n" ));
@@ -1230,7 +1232,7 @@
           {
             result = ps_tofixedarray( &cur, limit, max_objects,
                                       temp + i * max_objects, 0 );
-            if ( result < 0 )
+            if ( result < 0 || (FT_UInt)result < max_objects )
             {
               FT_ERROR(( "ps_parser_load_field:"
                          " expected %d integers in the %s subarray\n"
diff --git a/src/type1/t1load.c b/src/type1/t1load.c
index 4b5026b..d4171d9 100644
--- a/src/type1/t1load.c
+++ b/src/type1/t1load.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Type 1 font loader (body).                                           */
 /*                                                                         */
-/*  Copyright 1996-2013 by                                                 */
+/*  Copyright 1996-2014 by                                                 */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -1107,7 +1107,7 @@
 
     result = T1_ToFixedArray( parser, 6, temp, 3 );
 
-    if ( result < 0 )
+    if ( result < 6 )
     {
       parser->root.error = FT_THROW( Invalid_File_Format );
       return;
diff --git a/src/type42/t42parse.c b/src/type42/t42parse.c
index 3cdd8a1..9b66888 100644
--- a/src/type42/t42parse.c
+++ b/src/type42/t42parse.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Type 42 font parser (body).                                          */
 /*                                                                         */
-/*  Copyright 2002-2013 by                                                 */
+/*  Copyright 2002-2014 by                                                 */
 /*  Roberto Alameda.                                                       */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -255,12 +255,26 @@
     FT_Face     root   = (FT_Face)&face->root;
     FT_Fixed    temp[6];
     FT_Fixed    temp_scale;
+    FT_Int      result;
 
 
-    (void)T1_ToFixedArray( parser, 6, temp, 3 );
+    result = T1_ToFixedArray( parser, 6, temp, 3 );
+
+    if ( result < 6 )
+    {
+      parser->root.error = FT_THROW( Invalid_File_Format );
+      return;
+    }
 
     temp_scale = FT_ABS( temp[3] );
 
+    if ( temp_scale == 0 )
+    {
+      FT_ERROR(( "t1_parse_font_matrix: invalid font matrix\n" ));
+      parser->root.error = FT_THROW( 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).                              */
@@ -275,7 +289,7 @@
       temp[2] = FT_DivFix( temp[2], temp_scale );
       temp[4] = FT_DivFix( temp[4], temp_scale );
       temp[5] = FT_DivFix( temp[5], temp_scale );
-      temp[3] = 0x10000L;
+      temp[3] = temp[3] < 0 ? -0x10000L : 0x10000L;
     }
 
     matrix->xx = temp[0];
@@ -314,7 +328,7 @@
     if ( ft_isdigit( *cur ) || *cur == '[' )
     {
       T1_Encoding  encode          = &face->type1.encoding;
-      FT_UInt      count, n;
+      FT_Int       count, n;
       PS_Table     char_table      = &loader->encoding_table;
       FT_Memory    memory          = parser->root.memory;
       FT_Error     error;
@@ -329,7 +343,7 @@
         parser->root.cursor++;
       }
       else
-        count = (FT_UInt)T1_ToInt( parser );
+        count = (FT_Int)T1_ToInt( parser );
 
       T1_Skip_Spaces( parser );
       if ( parser->root.cursor >= limit )
@@ -417,7 +431,7 @@
 
           cur = parser->root.cursor;
 
-          if ( *cur == '/' && cur + 2 < limit && n < count )
+          if ( cur + 2 < limit && *cur == '/' && n < count )
           {
             FT_PtrDist  len;
 
@@ -426,6 +440,8 @@
 
             parser->root.cursor = cur;
             T1_Skip_PS_Token( parser );
+            if ( parser->root.cursor >= limit )
+              return;
             if ( parser->root.error )
               return;
 
@@ -439,6 +455,19 @@
 
             n++;
           }
+          else if ( only_immediates )
+          {
+            /* Since the current position is not updated for           */
+            /* immediates-only mode we would get an infinite loop if   */
+            /* we don't do anything here.                              */
+            /*                                                         */
+            /* This encoding array is not valid according to the type1 */
+            /* specification (it might be an encoding for a CID type1  */
+            /* font, however), so we conclude that this font is NOT a  */
+            /* type1 font.                                             */
+            parser->root.error = FT_THROW( Unknown_File_Format );
+            return;
+          }
         }
         else
         {
@@ -450,8 +479,8 @@
         T1_Skip_Spaces( parser );
       }
 
-      face->type1.encoding_type  = T1_ENCODING_TYPE_ARRAY;
-      parser->root.cursor        = cur;
+      face->type1.encoding_type = T1_ENCODING_TYPE_ARRAY;
+      parser->root.cursor       = cur;
     }
 
     /* Otherwise, we should have either `StandardEncoding', */
@@ -471,10 +500,7 @@
         face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1;
 
       else
-      {
-        FT_ERROR(( "t42_parse_encoding: invalid token\n" ));
-        parser->root.error = FT_THROW( Invalid_File_Format );
-      }
+        parser->root.error = FT_THROW( Ignore );
     }
   }