[CMAKE]
[reactos.git] / lib / 3rdparty / freetype / src / cff / cffgload.c
index 9330c05..e99ee70 100644 (file)
@@ -22,7 +22,6 @@
 #include FT_INTERNAL_STREAM_H
 #include FT_INTERNAL_SFNT_H
 #include FT_OUTLINE_H
-#include FT_INTERNAL_POSTSCRIPT_HINTS_H
 
 #include "cffobjs.h"
 #include "cffload.h"
 
     /* initialize Type2 decoder */
     decoder->cff          = cff;
-    decoder->num_globals  = cff->num_global_subrs;
+    decoder->num_globals  = cff->global_subrs_index.count;
     decoder->globals      = cff->global_subrs;
     decoder->globals_bias = cff_compute_bias(
                               cff->top_font.font_dict.charstring_type,
         goto Exit;
       }
 
-      FT_TRACE4(( "glyph index %d (subfont %d):\n", glyph_index, fd_index ));
+      FT_TRACE3(( "glyph index %d (subfont %d):\n", glyph_index, fd_index ));
 
       sub = cff->subfonts[fd_index];
 
     }
 #ifdef FT_DEBUG_LEVEL_TRACE
     else
-      FT_TRACE4(( "glyph index %d:\n", glyph_index ));
+      FT_TRACE3(( "glyph index %d:\n", glyph_index ));
 #endif
 
-    decoder->num_locals    = sub->num_local_subrs;
+    decoder->num_locals    = sub->local_subrs_index.count;
     decoder->locals        = sub->local_subrs;
     decoder->locals_bias   = cff_compute_bias(
                                decoder->cff->top_font.font_dict.charstring_type,
                                              charstring_len );
       decoder->seac = FALSE;
 
+      cff_free_glyph_data( face, &charstring, charstring_len );
+
       if ( error )
         goto Exit;
-
-      cff_free_glyph_data( face, &charstring, charstring_len );
     }
 
     /* Save the left bearing, advance and glyph width of the base */
                                              charstring_len );
       decoder->seac = FALSE;
 
+      cff_free_glyph_data( face, &charstring, charstring_len );
+
       if ( error )
         goto Exit;
-
-      cff_free_glyph_data( face, &charstring, charstring_len );
     }
 
     /* Restore the left side bearing, advance and glyph width */
             decoder->num_hints += num_args / 2;
           }
 
+          /* In a valid charstring there must be at least one byte */
+          /* after `hintmask' or `cntrmask' (e.g., for a `return'  */
+          /* instruction).  Additionally, there must be space for  */
+          /* `num_hints' bits.                                     */
+
+          if ( ( ip + ( ( decoder->num_hints + 7 ) >> 3 ) ) >= limit )
+            goto Syntax_Error;
+
           if ( hinter )
           {
             if ( op == cff_op_hintmask )
             FT_UInt maskbyte;
 
 
-            FT_TRACE4(( " (maskbytes: " ));
+            FT_TRACE4(( " (maskbytes:" ));
 
             for ( maskbyte = 0;
-                  maskbyte < (FT_UInt)(( decoder->num_hints + 7 ) >> 3);
+                  maskbyte < (FT_UInt)( ( decoder->num_hints + 7 ) >> 3 );
                   maskbyte++, ip++ )
-              FT_TRACE4(( "0x%02X", *ip ));
+              FT_TRACE4(( " 0x%02X", *ip ));
 
             FT_TRACE4(( ")\n" ));
           }
 #else
           ip += ( decoder->num_hints + 7 ) >> 3;
 #endif
-          if ( ip >= limit )
-            goto Syntax_Error;
           args = stack;
           break;
 
           /* subsequent `pop' operands should add the arguments,       */
           /* this is the implementation described for `unknown' other  */
           /* subroutines in the Type1 spec.                            */
+          /*                                                           */
+          /* XXX Fix return arguments (see discussion below).          */
           args -= 2 + ( args[-2] >> 16 );
+          if ( args < stack )
+            goto Stack_Underflow;
           break;
 
         case cff_op_pop:
 
           FT_TRACE4(( " pop (invalid op)\n" ));
 
+          /* XXX Increasing `args' is wrong: After a certain number of */
+          /* `pop's we get a stack overflow.  Reason for doing it is   */
+          /* code like this (actually found in a CFF font):            */
+          /*                                                           */
+          /*   17 1 3 callothersubr                                    */
+          /*   pop                                                     */
+          /*   callsubr                                                */
+          /*                                                           */
+          /* Since we handle `callothersubr' as a no-op, and           */
+          /* `callsubr' needs at least one argument, `pop' can't be a  */
+          /* no-op too as it basically should be.                      */
+          /*                                                           */
+          /* The right solution would be to provide real support for   */
+          /* `callothersubr' as done in `t1decode.c', however, given   */
+          /* the fact that CFF fonts with `pop' are invalid, it is     */
+          /* questionable whether it is worth the time.                */
           args++;
           break;
 
           return CFF_Err_Unimplemented_Feature;
         }
 
-      decoder->top = args;
+        decoder->top = args;
+
+        if ( decoder->top - stack >= CFF_MAX_OPERANDS )
+          goto Stack_Overflow;
 
       } /* general operator processing */
 
     /* this scaling is only relevant if the PS hinter isn't active */
     if ( cff->num_subfonts )
     {
-      FT_Byte  fd_index = cff_fd_select_get( &cff->fd_select,
-                                             glyph_index );
+      FT_ULong  top_upm, sub_upm;
+      FT_Byte   fd_index = cff_fd_select_get( &cff->fd_select,
+                                              glyph_index );
+
+      if ( fd_index >= cff->num_subfonts ) 
+        fd_index = cff->num_subfonts - 1;
 
-      FT_ULong  top_upm = cff->top_font.font_dict.units_per_em;
-      FT_ULong  sub_upm = cff->subfonts[fd_index]->font_dict.units_per_em;
+      top_upm = cff->top_font.font_dict.units_per_em;
+      sub_upm = cff->subfonts[fd_index]->font_dict.units_per_em;
 
 
       font_matrix = cff->subfonts[fd_index]->font_dict.font_matrix;
       /* now load the unscaled outline */
       error = cff_get_glyph_data( face, glyph_index,
                                   &charstring, &charstring_len );
-      if ( !error )
-      {
-        error = cff_decoder_prepare( &decoder, size, glyph_index );
-        if ( !error )
-        {
-          error = cff_decoder_parse_charstrings( &decoder,
-                                                 charstring,
-                                                 charstring_len );
+      if ( error )
+        goto Glyph_Build_Finished;
+
+      error = cff_decoder_prepare( &decoder, size, glyph_index );
+      if ( error )
+        goto Glyph_Build_Finished;
 
-          cff_free_glyph_data( face, &charstring, charstring_len );
+      error = cff_decoder_parse_charstrings( &decoder,
+                                             charstring,
+                                             charstring_len );
+
+      cff_free_glyph_data( face, &charstring, charstring_len );
 
+      if ( error )
+        goto Glyph_Build_Finished;
 
 #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;
         }
       }
 
-      /* save new glyph tables */
-      cff_builder_done( &decoder.builder );
+  Glyph_Build_Finished:
+      /* save new glyph tables, if no error */
+      if ( !error )
+        cff_builder_done( &decoder.builder );
+      /* XXX: anything to do for broken glyph entry? */
     }
 
 #ifdef FT_CONFIG_OPTION_INCREMENTAL