shithub: freetype+ttf2subf

Download patch

ref: 95867077e8f03476359f313a92013afe73d93ebf
parent: 916838ca68b0069212b2690c53e12d58c6679333
author: Werner Lemberg <[email protected]>
date: Thu Feb 12 03:33:20 EST 2004

* src/cid/cidload.c (cid_face_open): Always allocate
face->cid_stream so that we can deallocate it safely.


Make the PS parser more tolerant w.r.t. non-standard font data.  In
general, an error is only reported in case of a syntax error; a
wrong type is now simply ignored (if possible).  To be independent
of the order of various MM-specific keywords, the parse_shared_dict
routine has been removed -- the PS parser is now capable to skip
this data.  It no longer fails on parsing e.g.

  dup /WeightVector exch def

Since the token following /WeightVector isn't `[' (starting an
array) it is simply ignored.

* include/freetype/fterrdef.h: Define `FT_Err_Ignore' (0xA2) as a
new internal error value.

* src/type1/t1load.c (parse_blend_axis_types,
parse_blend_design_positions, parse_blend_design_map): Return
T1_Err_Ignore if no proper array is following the keyword.
(parse_weight_vector): Use T1_ToTokenArray, initializing `blend'
structure, if necessary.
Return T1_Err_Ignore if no proper array is following the keyword.
(parse_shared_dict): Removed.
(parse_encoding): Set parser->root.error to return T1_Err_Ignore
if no result can be obtained.
Check for errors before accessing `elements' array.
(t1_keywords): Remove /shareddict.
(parse_dict): Reset error if t1_load_keyword returns T1_Err_Ignore.
Set keyword_flag only in case of success.
Check error code if skipping an unrecognized token.
(T1_Open_Face) [!T1_CONFIG_OPTION_NO_MM_SUPPORT]: Call T1_Done_Blend
if blend commands haven't set up a proper MM font.

* src/psaux/psobjs.c (ps_parser_load_field_table): Remove special
code for synthetic fonts.
Return PSaux_Err_Ignore if no proper value has been found.

git/fs: mount .git/fs: mount/attach disallowed
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,15 +1,58 @@
-2003-02-09  Werner Lemberg  <[email protected]>
+2004-02-11  Werner Lemberg  <[email protected]>
 
+	* src/cid/cidload.c (cid_face_open): Always allocate
+	face->cid_stream so that we can deallocate it safely.
+
+2004-02-10  Werner Lemberg  <[email protected]>
+
+	Make the PS parser more tolerant w.r.t. non-standard font data.  In
+	general, an error is only reported in case of a syntax error; a
+	wrong type is now simply ignored (if possible).  To be independent
+	of the order of various MM-specific keywords, the parse_shared_dict
+	routine has been removed -- the PS parser is now capable to skip
+	this data.  It no longer fails on parsing e.g.
+
+	  dup /WeightVector exch def
+
+	Since the token following /WeightVector isn't `[' (starting an
+	array) it is simply ignored.
+
+	* include/freetype/fterrdef.h: Define `FT_Err_Ignore' (0xA2) as a
+	new internal error value.
+
+	* src/type1/t1load.c (parse_blend_axis_types,
+	parse_blend_design_positions, parse_blend_design_map): Return
+	T1_Err_Ignore if no proper array is following the keyword.
+	(parse_weight_vector): Use T1_ToTokenArray, initializing `blend'
+	structure, if necessary.
+	Return T1_Err_Ignore if no proper array is following the keyword.
+	(parse_shared_dict): Removed.
+	(parse_encoding): Set parser->root.error to return T1_Err_Ignore
+	if no result can be obtained.
+	Check for errors before accessing `elements' array.
+	(t1_keywords): Remove /shareddict.
+	(parse_dict): Reset error if t1_load_keyword returns T1_Err_Ignore.
+	Set keyword_flag only in case of success.
+	Check error code if skipping an unrecognized token.
+	(T1_Open_Face) [!T1_CONFIG_OPTION_NO_MM_SUPPORT]: Call T1_Done_Blend
+	if blend commands haven't set up a proper MM font.
+
+	* src/psaux/psobjs.c (ps_parser_load_field_table): Remove special
+	code for synthetic fonts.
+	Return PSaux_Err_Ignore if no proper value has been found.
+
+2004-02-09  Werner Lemberg  <[email protected]>
+
 	* src/cff/cffgload.c (cff_decoder_parse_charstrings)
 	<cff_op_endchar>: Preserve glyph width before calling
 	cff_operator_seac.
 
-2003-02-09  Martin Muskens  <[email protected]>
+2004-02-09  Martin Muskens  <[email protected]>
 
 	* src/cff/cffgload.c (cff_decoder_parse_charstrings): Handle special
 	first argument for `hintmask' and `cntrmask' operators also.
 
-2003-02-08  Werner Lemberg  <[email protected]>
+2004-02-08  Werner Lemberg  <[email protected]>
 
 	* builds/unix/configure.in: Call AC_SUBST for `enable_shared',
 	`hardcode_libdir_flag_spec', and `wl'.
@@ -22,7 +65,7 @@
 
 	* docs/CHANGES: Updated.
 
-2003-02-07  Keith Packard  <[email protected]>
+2004-02-07  Keith Packard  <[email protected]>
 
 	* src/bdf/bdfdrivr.c (BDF_Face_Init, BDF_Set_Pixel_Size): Fix
 	computation of various vertical and horizontal metric values.
@@ -30,24 +73,24 @@
 	* src/pcfdrivr.c (PCF_Set_Pixel_Size), src/pcfread (pcf_load_font):
 	Ditto.
 
-2003-02-07  Werner Lemberg  <[email protected]>
+2004-02-07  Werner Lemberg  <[email protected]>
 
 	* builds/win32/visualc/index.html,
 	builds/win32/visualc/freetype.dsp,
 	builds/win32/visualc/freetype.dsw, docs/CHANGES: Updated.
 
-2003-02-07  Vitaliy Pasternak  <[email protected]>
+2004-02-07  Vitaliy Pasternak  <[email protected]>
 
 	* builds/win32/visualc/freetype.sln,
 	builds/win32/visualc/freetype.vcproj: New files for VS.NET 2003.
 
-2003-02-03  Werner Lemberg  <[email protected]>
+2004-02-03  Werner Lemberg  <[email protected]>
 
 	* include/freetype/cache/ftccache.h (FTC_CACHE_LOOKUP_CMP):
 	Initialize `node'.
 	* src/type1/t1load.c (parse_dict): Initialize `have_integer'.
 
-2003-02-02  Werner Lemberg  <[email protected]>
+2004-02-02  Werner Lemberg  <[email protected]>
 
 	* src/type1/t1load.c (parse_dict): Handle `RD' and `-|' commands
 	outside of /Subrs or /CharStrings.  This can happen if there is
--- a/include/freetype/fterrdef.h
+++ b/include/freetype/fterrdef.h
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    FreeType error codes (specification).                                */
 /*                                                                         */
-/*  Copyright 2002 by                                                      */
+/*  Copyright 2002, 2004 by                                                */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -207,6 +207,8 @@
                 "opcode syntax error" )
   FT_ERRORDEF_( Stack_Underflow,                             0xA1, \
                 "argument stack underflow" )
+  FT_ERRORDEF_( Ignore,                                      0xA2, \
+                "ignore" )
 
   /* BDF errors */
 
--- a/src/cid/cidload.c
+++ b/src/cid/cidload.c
@@ -612,6 +612,9 @@
     if ( face_index < 0 )
       goto Exit;
 
+    if ( FT_NEW( face->cid_stream ) )
+      goto Exit;
+
     if ( parser->binary_length )
     {
       /* we must convert the data section from hexadecimal to binary */
@@ -620,9 +623,6 @@
                               parser->data_offset, face )               )
         goto Exit;
 
-      if ( FT_NEW( face->cid_stream ) )
-        goto Exit;
-
       FT_Stream_OpenMemory( face->cid_stream,
                             face->binary_data, parser->binary_length );
       face->cid.data_offset = 0;
@@ -629,7 +629,7 @@
     }
     else
     {
-      face->cid_stream = face->root.stream;
+      *face->cid_stream     = *face->root.stream;
       face->cid.data_offset = loader.parser.data_offset;
     }
 
--- a/src/psaux/psobjs.c
+++ b/src/psaux/psobjs.c
@@ -4,7 +4,7 @@
 /*                                                                         */
 /*    Auxiliary functions for PostScript fonts (body).                     */
 /*                                                                         */
-/*  Copyright 1996-2001, 2002, 2003 by                                     */
+/*  Copyright 1996-2001, 2002, 2003, 2004 by                               */
 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
 /*                                                                         */
 /*  This file is part of the FreeType project, and may only be used,       */
@@ -1280,10 +1280,6 @@
           if ( cur >= limit )
             break;
 
-          /* with synthetic fonts, it is possible to find a field twice */
-          if ( *(FT_String**)q )
-            break;
-
           if ( field->type == T1_FIELD_TYPE_KEY )
           {
             /* don't include leading `/' */
@@ -1359,7 +1355,7 @@
     T1_TokenRec  elements[T1_MAX_TABLE_ELEMENTS];
     T1_Token     token;
     FT_Int       num_elements;
-    FT_Error     error = 0;
+    FT_Error     error = PSaux_Err_Ok;
     FT_Byte*     old_cursor;
     FT_Byte*     old_limit;
     T1_FieldRec  fieldrec = *(T1_Field)field;
@@ -1374,8 +1370,10 @@
     ps_parser_to_token_array( parser, elements,
                               T1_MAX_TABLE_ELEMENTS, &num_elements );
     if ( num_elements < 0 )
-      goto Fail;
-
+    {
+      error = PSaux_Err_Ignore;
+      goto Exit;
+    }
     if ( num_elements > T1_MAX_TABLE_ELEMENTS )
       num_elements = T1_MAX_TABLE_ELEMENTS;
 
@@ -1408,10 +1406,6 @@
 
   Exit:
     return error;
-
-  Fail:
-    error = PSaux_Err_Invalid_File_Format;
-    goto Exit;
   }
 
 
--- a/src/type1/t1load.c
+++ b/src/type1/t1load.c
@@ -397,8 +397,13 @@
     /* take an array of objects */
     T1_ToTokenArray( &loader->parser, axis_tokens,
                      T1_MAX_MM_AXIS, &num_axis );
-    if ( num_axis <= 0 || num_axis > T1_MAX_MM_AXIS )
+    if ( num_axis < 0 )
     {
+      error = T1_Err_Ignore;
+      goto Exit;
+    }
+    if ( num_axis == 0 || num_axis > T1_MAX_MM_AXIS )
+    {
       FT_ERROR(( "parse_blend_axis_types: incorrect number of axes: %d\n",
                  num_axis ));
       error = T1_Err_Invalid_File_Format;
@@ -459,9 +464,15 @@
 
 
     /* get the array of design tokens -- compute number of designs */
-    T1_ToTokenArray( parser, design_tokens, T1_MAX_MM_DESIGNS, &num_designs );
-    if ( num_designs <= 0 || num_designs > T1_MAX_MM_DESIGNS )
+    T1_ToTokenArray( parser, design_tokens,
+                     T1_MAX_MM_DESIGNS, &num_designs );
+    if ( num_designs < 0 )
     {
+      error = T1_Err_Ignore;
+      goto Exit;
+    }
+    if ( num_designs == 0 || num_designs > T1_MAX_MM_DESIGNS )
+    {
       FT_ERROR(( "parse_blend_design_positions:" ));
       FT_ERROR(( " incorrect number of designs: %d\n",
                  num_designs ));
@@ -472,13 +483,13 @@
     {
       FT_Byte*  old_cursor = parser->root.cursor;
       FT_Byte*  old_limit  = parser->root.limit;
-      FT_UInt   n;
+      FT_Int    n;
 
 
       blend    = face->blend;
       num_axis = 0;  /* make compiler happy */
 
-      for ( n = 0; n < (FT_UInt)num_designs; n++ )
+      for ( n = 0; n < num_designs; n++ )
       {
         T1_TokenRec  axis_tokens[T1_MAX_MM_DESIGNS];
         T1_Token     token;
@@ -541,9 +552,15 @@
     FT_Memory    memory = face->root.memory;
 
 
-    T1_ToTokenArray( parser, axis_tokens, T1_MAX_MM_AXIS, &num_axis );
-    if ( num_axis <= 0 || num_axis > T1_MAX_MM_AXIS )
+    T1_ToTokenArray( parser, axis_tokens, 
+                     T1_MAX_MM_AXIS, &num_axis );
+    if ( num_axis < 0 )
     {
+      error = T1_Err_Ignore;
+      goto Exit;
+    }
+    if ( num_axis == 0 || num_axis > T1_MAX_MM_AXIS )
+    {
       FT_ERROR(( "parse_blend_design_map: incorrect number of axes: %d\n",
                  num_axis ));
       error = T1_Err_Invalid_File_Format;
@@ -615,26 +632,46 @@
   parse_weight_vector( T1_Face    face,
                        T1_Loader  loader )
   {
+    T1_TokenRec  design_tokens[T1_MAX_MM_DESIGNS];
+    FT_Int       num_designs;
     FT_Error     error  = T1_Err_Ok;
     T1_Parser    parser = &loader->parser;
     PS_Blend     blend  = face->blend;
-    T1_TokenRec  master;
-    FT_UInt      n;
+    T1_Token     token;
+    FT_Int       n;
     FT_Byte*     old_cursor;
     FT_Byte*     old_limit;
 
 
-    if ( !blend || blend->num_designs == 0 )
+    T1_ToTokenArray( parser, design_tokens,
+                     T1_MAX_MM_DESIGNS, &num_designs );
+    if ( num_designs < 0 )
     {
-      FT_ERROR(( "parse_weight_vector: too early!\n" ));
+      error = T1_Err_Ignore;
+      goto Exit;
+    }
+    if ( num_designs == 0 || num_designs > T1_MAX_MM_DESIGNS )
+    {
+      FT_ERROR(( "parse_weight_vector:" ));
+      FT_ERROR(( " incorrect number of designs: %d\n",
+                 num_designs ));
       error = T1_Err_Invalid_File_Format;
       goto Exit;
     }
 
-    T1_ToToken( parser, &master );
-    if ( master.type != T1_TOKEN_TYPE_ARRAY )
+    if ( !blend || !blend->num_designs )
     {
-      FT_ERROR(( "parse_weight_vector: incorrect format!\n" ));
+      error = t1_allocate_blend( face, num_designs, 0 );
+      if ( error )
+        goto Exit;
+      blend = face->blend;
+    }
+    else if ( blend->num_designs != (FT_UInt)num_designs )
+    {
+      FT_ERROR(( "parse_weight_vector:"
+                 " /BlendDesignPosition and /WeightVector have\n" ));
+      FT_ERROR(( "                    "
+                 " different number of elements!\n" ));
       error = T1_Err_Invalid_File_Format;
       goto Exit;
     }
@@ -642,12 +679,12 @@
     old_cursor = parser->root.cursor;
     old_limit  = parser->root.limit;
 
-    /* don't include the delimiting brackets */
-    parser->root.cursor = master.start + 1;
-    parser->root.limit  = master.limit - 1;
-
-    for ( n = 0; n < blend->num_designs; n++ )
+    for ( n = 0; n < num_designs; n++ )
     {
+      token = design_tokens + n;
+      parser->root.cursor = token->start;
+      parser->root.limit  = token->limit;
+
       blend->default_weight_vector[n] =
       blend->weight_vector[n]         = T1_ToFixed( parser, 0 );
     }
@@ -660,23 +697,6 @@
   }
 
 
-  /* the keyword `/shareddict' appears in some multiple master fonts   */
-  /* with a lot of Postscript garbage behind it (that's completely out */
-  /* of spec!); we detect it and terminate the parsing                 */
-  /*                                                                   */
-  static void
-  parse_shared_dict( T1_Face    face,
-                     T1_Loader  loader )
-  {
-    T1_Parser  parser = &loader->parser;
-
-    FT_UNUSED( face );
-
-
-    parser->root.cursor = parser->root.limit;
-    parser->root.error  = 0;
-  }
-
 #endif /* T1_CONFIG_OPTION_NO_MM_SUPPORT */
 
 
@@ -1007,9 +1027,9 @@
 
             parser->root.error = T1_Add_Table( char_table, charcode,
                                                cur, len + 1 );
-            char_table->elements[charcode][len] = '\0';
             if ( parser->root.error )
               return;
+            char_table->elements[charcode][len] = '\0';
 
             n++;
           }
@@ -1041,10 +1061,7 @@
         face->type1.encoding_type = T1_ENCODING_TYPE_ISOLATIN1;
 
       else
-      {
-        FT_ERROR(( "parse_encoding: invalid token!\n" ));
-        parser->root.error = T1_Err_Invalid_File_Format;
-      }
+        parser->root.error = T1_Err_Ignore;
     }
   }
 
@@ -1230,8 +1247,8 @@
       FT_Byte*  base;
 
 
-      /* the format is simple:                    */
-      /*   `/glyphname' + binary data             */
+      /* the format is simple:        */
+      /*   `/glyphname' + binary data */
 
       T1_Skip_Spaces( parser );
 
@@ -1395,7 +1412,7 @@
       /* We take index 0 and add it to the end of the table(s)    */
       /* and add our own /.notdef glyph to index 0.               */
 
-      /* 0 333 hsbw endchar                                      */
+      /* 0 333 hsbw endchar */
       FT_Byte  notdef_glyph[] = {0x8B, 0xF7, 0xE1, 0x0D, 0x0E};
       char*    notdef_name    = (char *)".notdef";
 
@@ -1469,7 +1486,6 @@
     T1_FIELD_CALLBACK( "BlendDesignMap", parse_blend_design_map )
     T1_FIELD_CALLBACK( "BlendAxisTypes", parse_blend_axis_types )
     T1_FIELD_CALLBACK( "WeightVector", parse_weight_vector )
-    T1_FIELD_CALLBACK( "shareddict", parse_shared_dict )
 #endif
 
     { 0, T1_FIELD_LOCATION_CID_INFO, T1_FIELD_TYPE_NONE, 0, 0, 0, 0, 0 }
@@ -1640,10 +1656,16 @@
                 parser->root.error = t1_load_keyword( face,
                                                       loader,
                                                       keyword );
-                if ( parser->root.error )
-                  return parser->root.error;
+                if ( parser->root.error == T1_Err_Ok )
+                  keyword_flag[0] = 1;
+                else
+                {
+                  if ( parser->root.error == T1_Err_Ignore )
+                    parser->root.error = T1_Err_Ok;
+                  else
+                    return parser->root.error;
+                }
               }
-              keyword_flag[0] = 1;
               break;
             }
 
@@ -1657,6 +1679,8 @@
       else
       {
         T1_Skip_PS_Token( parser );
+        if ( parser->root.error )
+          goto Exit;
         have_integer = 0;
       }
 
@@ -1663,6 +1687,7 @@
       T1_Skip_Spaces( parser );
     }
 
+  Exit:
     return parser->root.error;
   }
 
@@ -1755,6 +1780,30 @@
                         keyword_flags );
     if ( error )
       goto Exit;
+
+#ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
+
+    /* the following can happen for MM instances; we then treat the */
+    /* font as a normal PS font                                     */
+    if ( face->blend                                             &&
+         ( !face->blend->num_designs || !face->blend->num_axis ) )
+      T1_Done_Blend( face );
+
+    /* another safety check */
+    if ( face->blend )
+    {
+      FT_UInt  i;
+
+
+      for ( i = 0; i < face->blend->num_axis; i++ )
+        if ( !face->blend->design_map[i].num_points )
+        {
+          T1_Done_Blend( face );
+          break;
+        }
+    }
+
+#endif /* T1_CONFIG_OPTION_NO_MM_SUPPORT */
 
     /* now, propagate the subrs, charstrings, and glyphnames tables */
     /* to the Type1 data                                            */