Commit 40db4a9954304d14e5e1c85a09b28dde83bddae6

Werner Lemberg 2017-11-27T22:17:41

Allow (again) encoding vectors with more than 256 elements (#52464). In version 2.6.1, this has been disallowed to better reject malformed fonts; however, this restriction was too strong. This time, we only take the first 256 elements into account, since encoding arrays are always accessed with a 8bit integer, according to the PostScript Language Reference. * src/type1/t1load.c (parse_encoding): Implement it.

diff --git a/ChangeLog b/ChangeLog
index ef5d5b0..6bc3a58 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2017-11-27  Werner Lemberg  <wl@gnu.org>
+
+	Allow (again) encoding vectors with more than 256 elements (#52464).
+
+	In version 2.6.1, this has been disallowed to better reject
+	malformed fonts; however, this restriction was too strong.  This
+	time, we only take the first 256 elements into account, since
+	encoding arrays are always accessed with a 8bit integer, according
+	to the PostScript Language Reference.
+
+	* src/type1/t1load.c (parse_encoding): Implement it.
+
 2017-11-27  Jan Alexander Steffens (heftig)  <jan.steffens@gmail.com>
 
 	Fix last commit (#52522).
diff --git a/src/type1/t1load.c b/src/type1/t1load.c
index 9259df6..bdb986a 100644
--- a/src/type1/t1load.c
+++ b/src/type1/t1load.c
@@ -1309,7 +1309,7 @@
     if ( ft_isdigit( *cur ) || *cur == '[' )
     {
       T1_Encoding  encode          = &face->type1.encoding;
-      FT_Int       count, n;
+      FT_Int       count, array_size, n;
       PS_Table     char_table      = &loader->encoding_table;
       FT_Memory    memory          = parser->root.memory;
       FT_Error     error;
@@ -1326,13 +1326,12 @@
       else
         count = (FT_Int)T1_ToInt( parser );
 
-      /* only composite fonts (which we don't support) */
-      /* can have larger values                        */
+      array_size = count;
       if ( count > 256 )
       {
-        FT_ERROR(( "parse_encoding: invalid encoding array size\n" ));
-        parser->root.error = FT_THROW( Invalid_File_Format );
-        return;
+        FT_TRACE2(( "parse_encoding:"
+                    " only using first 256 encoding array entries\n" ));
+        array_size = 256;
       }
 
       T1_Skip_Spaces( parser );
@@ -1348,18 +1347,18 @@
       }
 
       /* we use a T1_Table to store our charnames */
-      loader->num_chars = encode->num_chars = count;
-      if ( FT_NEW_ARRAY( encode->char_index, count )     ||
-           FT_NEW_ARRAY( encode->char_name,  count )     ||
+      loader->num_chars = encode->num_chars = array_size;
+      if ( FT_NEW_ARRAY( encode->char_index, array_size )     ||
+           FT_NEW_ARRAY( encode->char_name,  array_size )     ||
            FT_SET_ERROR( psaux->ps_table_funcs->init(
-                           char_table, count, memory ) ) )
+                           char_table, array_size, memory ) ) )
       {
         parser->root.error = error;
         return;
       }
 
       /* We need to `zero' out encoding_table.elements */
-      for ( n = 0; n < count; n++ )
+      for ( n = 0; n < array_size; n++ )
       {
         char*  notdef = (char *)".notdef";
 
@@ -1452,11 +1451,14 @@
 
             len = (FT_UInt)( parser->root.cursor - cur );
 
-            parser->root.error = T1_Add_Table( char_table, charcode,
-                                               cur, len + 1 );
-            if ( parser->root.error )
-              return;
-            char_table->elements[charcode][len] = '\0';
+            if ( n < array_size )
+            {
+              parser->root.error = T1_Add_Table( char_table, charcode,
+                                                 cur, len + 1 );
+              if ( parser->root.error )
+                return;
+              char_table->elements[charcode][len] = '\0';
+            }
 
             n++;
           }