< prev index next >

src/java.desktop/share/native/libfreetype/src/cff/cffparse.c

Print this page

        

@@ -75,40 +75,109 @@
   Exit:
     return error;
   }
 
 
+#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
+  static void
+  finalize_t2_strings( FT_Memory  memory,
+                       void*      data,
+                       void*      user )
+  {
+    CFF_T2_String  t2 = (CFF_T2_String)data;
+
+
+    FT_UNUSED( user );
+
+    memory->free( memory, t2->start );
+    memory->free( memory, data );
+  }
+#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
+
+
   FT_LOCAL_DEF( void )
   cff_parser_done( CFF_Parser  parser )
   {
     FT_Memory  memory = parser->library->memory;    /* for FT_FREE */
 
 
     FT_FREE( parser->stack );
+
+#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
+    FT_List_Finalize( &parser->t2_strings,
+                      finalize_t2_strings,
+                      memory,
+                      NULL );
+#endif
+  }
+
+
+  /* Assuming `first >= last'. */
+
+  static FT_Error
+  cff_parser_within_limits( CFF_Parser  parser,
+                            FT_Byte*    first,
+                            FT_Byte*    last )
+  {
+#ifndef CFF_CONFIG_OPTION_OLD_ENGINE
+
+    /* Fast path for regular FreeType builds with the "new" engine; */
+    /*   `first >= parser->start' can be assumed.                   */
+
+    FT_UNUSED( first );
+
+    return last < parser->limit ? FT_Err_Ok : FT_THROW( Invalid_Argument );
+
+#else /* CFF_CONFIG_OPTION_OLD_ENGINE */
+
+    FT_ListNode  node;
+
+
+    if ( first >= parser->start &&
+         last  <  parser->limit )
+      return FT_Err_Ok;
+
+    node = parser->t2_strings.head;
+
+    while ( node )
+    {
+      CFF_T2_String  t2 = (CFF_T2_String)node->data;
+
+
+      if ( first >= t2->start &&
+           last  <  t2->limit )
+        return FT_Err_Ok;
+
+      node = node->next;
+    }
+
+    return FT_THROW( Invalid_Argument );
+
+#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
   }
 
 
   /* read an integer */
   static FT_Long
-  cff_parse_integer( FT_Byte*  start,
-                     FT_Byte*  limit )
+  cff_parse_integer( CFF_Parser  parser,
+                     FT_Byte*    start )
   {
     FT_Byte*  p   = start;
     FT_Int    v   = *p++;
     FT_Long   val = 0;
 
 
     if ( v == 28 )
     {
-      if ( p + 2 > limit )
+      if ( cff_parser_within_limits( parser, p, p + 1 ) )
         goto Bad;
 
       val = (FT_Short)( ( (FT_UShort)p[0] << 8 ) | p[1] );
     }
     else if ( v == 29 )
     {
-      if ( p + 4 > limit )
+      if ( cff_parser_within_limits( parser, p, p + 3 ) )
         goto Bad;
 
       val = (FT_Long)( ( (FT_ULong)p[0] << 24 ) |
                        ( (FT_ULong)p[1] << 16 ) |
                        ( (FT_ULong)p[2] <<  8 ) |

@@ -118,18 +187,18 @@
     {
       val = v - 139;
     }
     else if ( v < 251 )
     {
-      if ( p + 1 > limit )
+      if ( cff_parser_within_limits( parser, p, p ) )
         goto Bad;
 
       val = ( v - 247 ) * 256 + p[0] + 108;
     }
     else
     {
-      if ( p + 1 > limit )
+      if ( cff_parser_within_limits( parser, p, p ) )
         goto Bad;
 
       val = -( v - 251 ) * 256 - p[0] - 108;
     }
 

@@ -174,12 +243,12 @@
   };
 
 
   /* read a real */
   static FT_Fixed
-  cff_parse_real( FT_Byte*  start,
-                  FT_Byte*  limit,
+  cff_parse_real( CFF_Parser  parser,
+                  FT_Byte*    start,
                   FT_Long   power_ten,
                   FT_Long*  scaling )
   {
     FT_Byte*  p = start;
     FT_Int    nib;

@@ -212,11 +281,11 @@
       if ( phase )
       {
         p++;
 
         /* Make sure we don't read past the end. */
-        if ( p >= limit )
+        if ( cff_parser_within_limits( parser, p, p ) )
           goto Bad;
       }
 
       /* Get the nibble. */
       nib   = (FT_Int)( p[0] >> phase ) & 0xF;

@@ -249,11 +318,11 @@
         if ( phase )
         {
           p++;
 
           /* Make sure we don't read past the end. */
-          if ( p >= limit )
+          if ( cff_parser_within_limits( parser, p, p ) )
             goto Bad;
         }
 
         /* Get the nibble. */
         nib   = ( p[0] >> phase ) & 0xF;

@@ -288,11 +357,11 @@
         if ( phase )
         {
           p++;
 
           /* Make sure we don't read past the end. */
-          if ( p >= limit )
+          if ( cff_parser_within_limits( parser, p, p ) )
             goto Bad;
         }
 
         /* Get the nibble. */
         nib   = ( p[0] >> phase ) & 0xF;

@@ -455,11 +524,11 @@
                  FT_Byte**   d )
   {
     if ( **d == 30 )
     {
       /* binary-coded decimal is truncated to integer */
-      return cff_parse_real( *d, parser->limit, 0, NULL ) >> 16;
+      return cff_parse_real( parser, *d, 0, NULL ) >> 16;
     }
 
     else if ( **d == 255 )
     {
       /* 16.16 fixed point is used internally for CFF2 blend results. */

@@ -481,25 +550,25 @@
                      (FT_UInt32)*( d[0] + 3 )         ) + 0x80U ) >> 8 );
 #endif
     }
 
     else
-      return cff_parse_integer( *d, parser->limit );
+      return cff_parse_integer( parser, *d );
   }
 
 
   /* read a floating point number, either integer or real */
   static FT_Fixed
   do_fixed( CFF_Parser  parser,
             FT_Byte**   d,
             FT_Long     scaling )
   {
     if ( **d == 30 )
-      return cff_parse_real( *d, parser->limit, scaling, NULL );
+      return cff_parse_real( parser, *d, scaling, NULL );
     else
     {
-      FT_Long  val = cff_parse_integer( *d, parser->limit );
+      FT_Long  val = cff_parse_integer( parser, *d );
 
 
       if ( scaling )
       {
         if ( FT_ABS( val ) > power_ten_limits[scaling] )

@@ -560,18 +629,18 @@
                            FT_Long*    scaling )
   {
     FT_ASSERT( scaling );
 
     if ( **d == 30 )
-      return cff_parse_real( *d, parser->limit, 0, scaling );
+      return cff_parse_real( parser, *d, 0, scaling );
     else
     {
       FT_Long  number;
       FT_Int   integer_length;
 
 
-      number = cff_parse_integer( d[0], d[1] );
+      number = cff_parse_integer( parser, d[0] );
 
       if ( number > 0x7FFFL )
       {
         for ( integer_length = 5; integer_length < 10; integer_length++ )
           if ( number < power_tens[integer_length] )

@@ -1120,22 +1189,10 @@
 
 
 #endif /* FT_DEBUG_LEVEL_TRACE */
 
 
-#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
-  static void
-  destruct_t2s_item( FT_Memory  memory,
-                     void*      data,
-                     void*      user )
-  {
-    FT_UNUSED( user );
-    memory->free( memory, data );
-  }
-#endif /* CFF_CONFIG_OPTION_OLD_ENGINE */
-
-
   FT_LOCAL_DEF( FT_Error )
   cff_parser_run( CFF_Parser  parser,
                   FT_Byte*    start,
                   FT_Byte*    limit )
   {

@@ -1145,15 +1202,10 @@
 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
     PSAux_Service  psaux;
 
     FT_Library  library = parser->library;
     FT_Memory   memory  = library->memory;
-
-    FT_ListRec  t2s;
-
-
-    FT_ZERO( &t2s );
 #endif
 
     parser->top    = parser->stack;
     parser->start  = start;
     parser->limit  = limit;

@@ -1212,10 +1264,12 @@
         FT_Byte*     charstring_base;
         FT_ULong     charstring_len;
 
         FT_Fixed*    stack;
         FT_ListNode  node;
+        CFF_T2_String t2;
+        size_t        t2_size;
         FT_Byte*     q;
 
 
         charstring_base = ++p;
 

@@ -1259,20 +1313,30 @@
         node = (FT_ListNode)memory->alloc( memory,
                                            sizeof ( FT_ListNodeRec ) );
         if ( !node )
           goto Out_Of_Memory_Error;
 
+        FT_List_Add( &parser->t2_strings, node );
+
+        t2 = (CFF_T2_String)memory->alloc( memory,
+                                           sizeof ( CFF_T2_StringRec ) );
+        if ( !t2 )
+          goto Out_Of_Memory_Error;
+
+        node->data = t2;
+
         /* `5' is the conservative upper bound of required bytes per stack */
         /* element.                                                        */
-        q = (FT_Byte*)memory->alloc( memory,
-                                     5 * ( decoder.top - decoder.stack ) );
+
+        t2_size = 5 * ( decoder.top - decoder.stack );
+
+        q = (FT_Byte*)memory->alloc( memory, t2_size );
         if ( !q )
           goto Out_Of_Memory_Error;
 
-        node->data = q;
-
-        FT_List_Add( &t2s, node );
+        t2->start = q;
+        t2->limit = q + t2_size;
 
         stack = decoder.stack;
 
         while ( stack < decoder.top )
         {

@@ -1529,13 +1593,10 @@
       }
       p++;
     } /* while ( p < limit ) */
 
   Exit:
-#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
-    FT_List_Finalize( &t2s, destruct_t2s_item, memory, NULL );
-#endif
     return error;
 
 #ifdef CFF_CONFIG_OPTION_OLD_ENGINE
   Out_Of_Memory_Error:
     error = FT_THROW( Out_Of_Memory );
< prev index next >