< prev index next >

src/java.desktop/share/native/libfreetype/src/psaux/cffdecode.c

Print this page

        

@@ -1,21 +1,21 @@
-/***************************************************************************/
-/*                                                                         */
-/*  cffdecode.c                                                            */
-/*                                                                         */
-/*    PostScript CFF (Type 2) decoding routines (body).                    */
-/*                                                                         */
-/*  Copyright 2017-2018 by                                                 */
-/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
-/*                                                                         */
-/*  This file is part of the FreeType project, and may only be used,       */
-/*  modified, and distributed under the terms of the FreeType project      */
-/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
-/*  this file you indicate that you have read the license and              */
-/*  understand and accept it fully.                                        */
-/*                                                                         */
-/***************************************************************************/
+/****************************************************************************
+ *
+ * cffdecode.c
+ *
+ *   PostScript CFF (Type 2) decoding routines (body).
+ *
+ * Copyright (C) 2017-2019 by
+ * David Turner, Robert Wilhelm, and Werner Lemberg.
+ *
+ * This file is part of the FreeType project, and may only be used,
+ * modified, and distributed under the terms of the FreeType project
+ * license, LICENSE.TXT.  By continuing to use, modify, or distribute
+ * this file you indicate that you have read the license and
+ * understand and accept it fully.
+ *
+ */
 
 
 #include <ft2build.h>
 #include FT_FREETYPE_H
 #include FT_INTERNAL_DEBUG_H

@@ -26,18 +26,18 @@
 #include "psobjs.h"
 
 #include "psauxerr.h"
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
-  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
-  /* messages during execution.                                            */
-  /*                                                                       */
+  /**************************************************************************
+   *
+   * The macro FT_COMPONENT is used in trace mode.  It is an implicit
+   * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
+   * messages during execution.
+   */
 #undef  FT_COMPONENT
-#define FT_COMPONENT  trace_cffdecode
+#define FT_COMPONENT  cffdecode
 
 
 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
 
   typedef enum  CFF_Operator_

@@ -233,12 +233,12 @@
     {
       FT_ERROR(( "cff_operator_seac: invalid nested seac\n" ));
       return FT_THROW( Syntax_Error );
     }
 
-    adx += decoder->builder.left_bearing.x;
-    ady += decoder->builder.left_bearing.y;
+    adx = ADD_LONG( adx, decoder->builder.left_bearing.x );
+    ady = ADD_LONG( ady, decoder->builder.left_bearing.y );
 
 #ifdef FT_CONFIG_OPTION_INCREMENTAL
     /* Incremental fonts don't necessarily have valid charsets.        */
     /* They use the character code, not the glyph index, in this case. */
     if ( face->root.internal->incremental_interface )

@@ -376,27 +376,30 @@
   /**********                                                      *********/
   /*************************************************************************/
   /*************************************************************************/
   /*************************************************************************/
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    cff_compute_bias                                                   */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Computes the bias value in dependence of the number of glyph       */
-  /*    subroutines.                                                       */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    in_charstring_type :: The `CharstringType' value of the top DICT   */
-  /*                          dictionary.                                  */
-  /*                                                                       */
-  /*    num_subrs          :: The number of glyph subroutines.             */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    The bias value.                                                    */
+  /**************************************************************************
+   *
+   * @Function:
+   *   cff_compute_bias
+   *
+   * @Description:
+   *   Computes the bias value in dependence of the number of glyph
+   *   subroutines.
+   *
+   * @Input:
+   *   in_charstring_type ::
+   *     The `CharstringType' value of the top DICT
+   *     dictionary.
+   *
+   *   num_subrs ::
+   *     The number of glyph subroutines.
+   *
+   * @Return:
+   *   The bias value.
+   */
   static FT_Int
   cff_compute_bias( FT_Int   in_charstring_type,
                     FT_UInt  num_subrs )
   {
     FT_Int  result;

@@ -462,32 +465,36 @@
   }
 
 
 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    cff_decoder_parse_charstrings                                      */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Parses a given Type 2 charstrings program.                         */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    decoder         :: The current Type 1 decoder.                     */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    charstring_base :: The base of the charstring stream.              */
-  /*                                                                       */
-  /*    charstring_len  :: The length in bytes of the charstring stream.   */
-  /*                                                                       */
-  /*    in_dict         :: Set to 1 if function is called from top or      */
-  /*                       private DICT (needed for Multiple Master CFFs). */
-  /*                                                                       */
-  /* <Return>                                                              */
-  /*    FreeType error code.  0 means success.                             */
-  /*                                                                       */
+  /**************************************************************************
+   *
+   * @Function:
+   *   cff_decoder_parse_charstrings
+   *
+   * @Description:
+   *   Parses a given Type 2 charstrings program.
+   *
+   * @InOut:
+   *   decoder ::
+   *     The current Type 1 decoder.
+   *
+   * @Input:
+   *   charstring_base ::
+   *     The base of the charstring stream.
+   *
+   *   charstring_len ::
+   *     The length in bytes of the charstring stream.
+   *
+   *   in_dict ::
+   *     Set to 1 if function is called from top or
+   *     private DICT (needed for Multiple Master CFFs).
+   *
+   * @Return:
+   *   FreeType error code.  0 means success.
+   */
   FT_LOCAL_DEF( FT_Error )
   cff_decoder_parse_charstrings( CFF_Decoder*  decoder,
                                  FT_Byte*      charstring_base,
                                  FT_ULong      charstring_len,
                                  FT_Bool       in_dict )

@@ -541,14 +548,14 @@
     {
       CFF_Operator  op;
       FT_Byte       v;
 
 
-      /********************************************************************/
-      /*                                                                  */
-      /* Decode operator or operand                                       */
-      /*                                                                  */
+      /*********************************************************************
+       *
+       * Decode operator or operand
+       */
       v = *ip++;
       if ( v >= 32 || v == 28 )
       {
         FT_Int    shift = 16;
         FT_Int32  val;

@@ -851,10 +858,19 @@
           case cff_op_flex:
           case cff_op_hflex1:
           case cff_op_flex1:
           case cff_op_callsubr:
           case cff_op_callgsubr:
+            /* deprecated opcodes */
+          case cff_op_dotsection:
+            /* invalid Type 1 opcodes */
+          case cff_op_hsbw:
+          case cff_op_closepath:
+          case cff_op_callothersubr:
+          case cff_op_seac:
+          case cff_op_sbw:
+          case cff_op_setcurrentpoint:
             goto MM_Error;
 
           default:
             break;
           }

@@ -946,14 +962,14 @@
         case cff_op_hstem:
         case cff_op_vstem:
         case cff_op_hstemhm:
         case cff_op_vstemhm:
           /* the number of arguments is always even here */
-          FT_TRACE4((
-              op == cff_op_hstem   ? " hstem\n"   :
-            ( op == cff_op_vstem   ? " vstem\n"   :
-            ( op == cff_op_hstemhm ? " hstemhm\n" : " vstemhm\n" ) ) ));
+          FT_TRACE4(( "%s\n",
+              op == cff_op_hstem   ? " hstem"   :
+            ( op == cff_op_vstem   ? " vstem"   :
+            ( op == cff_op_hstemhm ? " hstemhm" : " vstemhm" ) ) ));
 
           if ( hinter )
             hinter->stems( hinter->hints,
                            ( op == cff_op_hstem || op == cff_op_hstemhm ),
                            num_args / 2,

@@ -963,11 +979,12 @@
           args = stack;
           break;
 
         case cff_op_hintmask:
         case cff_op_cntrmask:
-          FT_TRACE4(( op == cff_op_hintmask ? " hintmask" : " cntrmask" ));
+          FT_TRACE4(( "%s", op == cff_op_hintmask ? " hintmask"
+                                                  : " cntrmask" ));
 
           /* implement vstem when needed --                        */
           /* the specification doesn't say it, but this also works */
           /* with the 'cntrmask' operator                          */
           /*                                                       */

@@ -1076,12 +1093,12 @@
         case cff_op_vlineto:
           {
             FT_Int  phase = ( op == cff_op_hlineto );
 
 
-            FT_TRACE4(( op == cff_op_hlineto ? " hlineto\n"
-                                             : " vlineto\n" ));
+            FT_TRACE4(( "%s\n", op == cff_op_hlineto ? " hlineto"
+                                                     : " vlineto" ));
 
             if ( num_args < 0 )
               goto Stack_Underflow;
 
             /* there exist subsetted fonts (found in PDFs) */

@@ -1248,12 +1265,12 @@
           {
             FT_Int  phase;
             FT_Int  nargs;
 
 
-            FT_TRACE4(( op == cff_op_vhcurveto ? " vhcurveto\n"
-                                               : " hvcurveto\n" ));
+            FT_TRACE4(( "%s\n", op == cff_op_vhcurveto ? " vhcurveto"
+                                                       : " hvcurveto" ));
 
             if ( cff_builder_start_point( builder, x, y ) )
               goto Fail;
 
             if ( num_args < 4 )

@@ -1537,23 +1554,23 @@
               dy    = ADD_LONG( dy, temp[1] );
               temp += 2;
             }
 
             if ( dx < 0 )
-              dx = -dx;
+              dx = NEG_LONG( dx );
             if ( dy < 0 )
-              dy = -dy;
+              dy = NEG_LONG( dy );
 
             /* strange test, but here it is... */
             horizontal = ( dx > dy );
 
             for ( count = 5; count > 0; count-- )
             {
               x = ADD_LONG( x, args[0] );
               y = ADD_LONG( y, args[1] );
               cff_builder_add_point( builder, x, y,
-                                     (FT_Bool)( count == 3 ) );
+                                     FT_BOOL( count == 3 ) );
               args += 2;
             }
 
             /* is last operand an x- or y-delta? */
             if ( horizontal )

@@ -1587,11 +1604,11 @@
             for ( count = 6; count > 0; count-- )
             {
               x = ADD_LONG( x, args[0] );
               y = ADD_LONG( y, args[1] );
               cff_builder_add_point( builder, x, y,
-                                     (FT_Bool)( count == 4 || count == 1 ) );
+                                     FT_BOOL( count == 4 || count == 1 ) );
               args += 2;
             }
 
             args = stack;
           }

@@ -1703,20 +1720,24 @@
           args[0] = -args[0];
           args++;
           break;
 
         case cff_op_random:
+          {
+            FT_UInt32*  randval = in_dict ? &decoder->cff->top_font.random
+                                          : &decoder->current_subfont->random;
+
+
           FT_TRACE4(( " random\n" ));
 
           /* only use the lower 16 bits of `random'  */
           /* to generate a number in the range (0;1] */
-          args[0] = (FT_Fixed)
-                      ( ( decoder->current_subfont->random & 0xFFFF ) + 1 );
+            args[0] = (FT_Fixed)( ( *randval & 0xFFFF ) + 1 );
           args++;
 
-          decoder->current_subfont->random =
-            cff_random( decoder->current_subfont->random );
+            *randval = cff_random( *randval );
+          }
           break;
 
         case cff_op_mul:
           FT_TRACE4(( " mul\n" ));
 

@@ -1725,11 +1746,14 @@
           break;
 
         case cff_op_sqrt:
           FT_TRACE4(( " sqrt\n" ));
 
-          if ( args[0] > 0 )
+          /* without upper limit the loop below might not finish */
+          if ( args[0] > 0x7FFFFFFFL )
+            args[0] = 46341;
+          else if ( args[0] > 0 )
           {
             FT_Fixed  root = args[0];
             FT_Fixed  new_root;
 
 

@@ -1798,10 +1822,11 @@
             if ( args < stack )
               goto Stack_Underflow;
 
             if ( idx >= 0 )
             {
+              idx = idx % count;
               while ( idx > 0 )
               {
                 FT_Fixed  tmp = args[count - 1];
                 FT_Int    i;
 

@@ -1812,10 +1837,14 @@
                 idx--;
               }
             }
             else
             {
+              /* before C99 it is implementation-defined whether    */
+              /* the result of `%' is negative if the first operand */
+              /* is negative                                        */
+              idx = -( NEG_INT( idx ) % count );
               while ( idx < 0 )
               {
                 FT_Fixed  tmp = args[0];
                 FT_Int    i;
 

@@ -1912,28 +1941,32 @@
           break;
 
         case cff_op_blend:
           /* this operator was removed from the Type2 specification */
           /* in version 16-March-2000                               */
+          if ( num_designs )
           {
             FT_Int  num_results = (FT_Int)( args[0] >> 16 );
 
 
             FT_TRACE4(( " blend\n" ));
 
             if ( num_results < 0 )
               goto Syntax_Error;
 
-            if ( num_results * (FT_Int)num_designs > num_args )
+            if ( num_results > num_args                       ||
+                 num_results * (FT_Int)num_designs > num_args )
               goto Stack_Underflow;
 
             /* since we currently don't handle interpolation of multiple */
             /* master fonts, return the `num_results' values of the      */
             /* first master                                              */
             args     -= num_results * ( num_designs - 1 );
             num_args -= num_results * ( num_designs - 1 );
           }
+          else
+            goto Syntax_Error;
           break;
 
         case cff_op_dotsection:
           /* this operator is deprecated and ignored by the parser */
           FT_TRACE4(( " dotsection\n" ));

@@ -1996,24 +2029,35 @@
           y    = ADD_LONG( decoder->builder.pos_y, args[1] );
           args = stack;
           break;
 
         case cff_op_callothersubr:
+          {
+            FT_Fixed  arg;
+
+
           /* this is an invalid Type 2 operator; however, there        */
-          /* exist fonts which are incorrectly converted from probably */
-          /* Type 1 to CFF, and some parsers seem to accept it         */
+            /* exist fonts which are incorrectly converted from        */
+            /* probably Type 1 to CFF, and some parsers seem to accept */
+            /* it                                                      */
 
           FT_TRACE4(( " callothersubr (invalid op)\n" ));
 
           /* subsequent `pop' operands should add the arguments,       */
-          /* this is the implementation described for `unknown' other  */
-          /* subroutines in the Type1 spec.                            */
+            /* 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 );
+
+            arg = 2 + ( args[-2] >> 16 );
+            if ( arg >= CFF_MAX_OPERANDS )
+              goto Stack_Underflow;
+
+            args -= arg;
           if ( args < stack )
             goto Stack_Underflow;
+          }
           break;
 
         case cff_op_pop:
           /* this is an invalid Type 2 operator; however, there        */
           /* exist fonts which are incorrectly converted from probably */

@@ -2249,32 +2293,38 @@
   }
 
 #endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
 
 
-  /*************************************************************************/
-  /*                                                                       */
-  /* <Function>                                                            */
-  /*    cff_decoder_init                                                   */
-  /*                                                                       */
-  /* <Description>                                                         */
-  /*    Initializes a given glyph decoder.                                 */
-  /*                                                                       */
-  /* <InOut>                                                               */
-  /*    decoder :: A pointer to the glyph builder to initialize.           */
-  /*                                                                       */
-  /* <Input>                                                               */
-  /*    face      :: The current face object.                              */
-  /*                                                                       */
-  /*    size      :: The current size object.                              */
-  /*                                                                       */
-  /*    slot      :: The current glyph object.                             */
-  /*                                                                       */
-  /*    hinting   :: Whether hinting is active.                            */
-  /*                                                                       */
-  /*    hint_mode :: The hinting mode.                                     */
-  /*                                                                       */
+  /**************************************************************************
+   *
+   * @Function:
+   *   cff_decoder_init
+   *
+   * @Description:
+   *   Initializes a given glyph decoder.
+   *
+   * @InOut:
+   *   decoder ::
+   *     A pointer to the glyph builder to initialize.
+   *
+   * @Input:
+   *   face ::
+   *     The current face object.
+   *
+   *   size ::
+   *     The current size object.
+   *
+   *   slot ::
+   *     The current glyph object.
+   *
+   *   hinting ::
+   *     Whether hinting is active.
+   *
+   *   hint_mode ::
+   *     The hinting mode.
+   */
   FT_LOCAL_DEF( void )
   cff_decoder_init( CFF_Decoder*                     decoder,
                     TT_Face                          face,
                     CFF_Size                         size,
                     CFF_GlyphSlot                    slot,
< prev index next >