freetype-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[freetype2] OpenType-1.8 88ad21f 6/6: [cff] Make cff parser stack dynami


From: Dave Arnold
Subject: [freetype2] OpenType-1.8 88ad21f 6/6: [cff] Make cff parser stack dynamic
Date: Thu, 17 Nov 2016 16:23:04 +0000 (UTC)

branch: OpenType-1.8
commit 88ad21fbe54a5bad1d169e127094e26f1f840fba
Author: Dave Arnold <address@hidden>
Commit: Dave Arnold <address@hidden>

    [cff] Make cff parser stack dynamic
    
    Allocate and free parser->stack. Allow maxstack to increase the default.
    
    Do validation of maxstack at parse time; make it a CALLBACK.
    
    Defer support for > 256 FDs in cff_font_load().
---
 src/cff/cf2intrp.c |    9 ++------
 src/cff/cffload.c  |   39 +++++++++++++++++++++++---------
 src/cff/cffparse.c |   64 ++++++++++++++++++++++++++++++++++++++++++++++++----
 src/cff/cffparse.h |   15 +++++++++---
 src/cff/cfftoken.h |   17 +++++++-------
 5 files changed, 110 insertions(+), 34 deletions(-)

diff --git a/src/cff/cf2intrp.c b/src/cff/cf2intrp.c
index 9b19077..66a2371 100644
--- a/src/cff/cf2intrp.c
+++ b/src/cff/cf2intrp.c
@@ -562,13 +562,8 @@
      */
 
     /* allocate an operand stack */
-    if ( font->isCFF2 )
-    {
-      /* CFF2 font may increase the operand stack size */
-      FT_UInt maxstack = cf2_getMaxstack( decoder );
-      if ( maxstack > stackSize )
-        stackSize = maxstack;
-    }
+    stackSize = font->isCFF2 ? cf2_getMaxstack( decoder ) : 
+                               CF2_OPERAND_STACK_SIZE;
     opStack = cf2_stack_init( memory, error, stackSize );
     if ( !opStack )
     {
diff --git a/src/cff/cffload.c b/src/cff/cffload.c
index 4c65c94..1a64543 100644
--- a/src/cff/cffload.c
+++ b/src/cff/cffload.c
@@ -1740,9 +1740,10 @@ Exit:
     CFF_FontRecDict  top  = &subfont->font_dict;
     CFF_Private      priv = &subfont->private_dict;
     FT_Stream        stream = font->stream;
+    FT_UInt          stackSize;
 
     if ( top->private_offset == 0 || top->private_size == 0 )
-      goto Exit;        /* no private DICT, do nothing */
+      goto Exit2;       /* no private DICT, do nothing */
 
     /* store handle needed to access memory, vstore for blend */
     subfont->blend.font = font;
@@ -1762,12 +1763,17 @@ Exit:
     subfont->lenNDV = lenNDV;
     subfont->NDV = NDV;
 
-    cff_parser_init( &parser,
-                     font->cff2 ? CFF2_CODE_PRIVATE : CFF_CODE_PRIVATE,
-                     priv,
-                     font->library,
-                     top->num_designs,
-                     top->num_axes );
+    stackSize = font->cff2 ? font->top_font.font_dict.maxstack :
+                             CFF_MAX_STACK_DEPTH + 1;
+
+    if ( cff_parser_init( &parser,
+                          font->cff2 ? CFF2_CODE_PRIVATE : CFF_CODE_PRIVATE,
+                          priv,
+                          font->library,
+                          stackSize,
+                          top->num_designs,
+                          top->num_axes ) )
+      goto Exit;
     if ( FT_STREAM_SEEK( font->base_offset + top->private_offset ) ||
          FT_FRAME_ENTER( top->private_size )                 )
       goto Exit;
@@ -1784,7 +1790,12 @@ Exit:
     priv->num_blue_values &= ~1;
 
   Exit:
-    cff_blend_clear( subfont );
+    /* clean up */
+    cff_blend_clear( subfont ); /* clear blend stack */
+    cff_parser_done( &parser ); /* free parser stack */
+
+  Exit2:
+    /* no clean up (parser not inited) */
     return error;
   }
 
@@ -1811,12 +1822,15 @@ Exit:
     CFF_Private      priv = &subfont->private_dict;
     FT_Bool          cff2 = (code == CFF2_CODE_TOPDICT ||
                              code == CFF2_CODE_FONTDICT );
+    FT_UInt          stackSize = cff2 ? CFF2_DEFAULT_STACK : 
CFF_MAX_STACK_DEPTH;
 
-
+    /* Note: we use default stack size for CFF2 Font DICT because   */
+    /* Top and Font DICTs are not allowed to have blend operators   */
     cff_parser_init( &parser,
                      code,
                      &subfont->font_dict,
                      library,
+                     stackSize,
                      0,
                      0 );
 
@@ -1902,6 +1916,8 @@ Exit:
     }
 
   Exit:
+    cff_parser_done( &parser ); /* free parser stack */
+
     return error;
   }
 
@@ -2113,7 +2129,8 @@ Exit:
         goto Exit;
 
       /* Font Dicts are not limited to 256 for CFF2 */
-      if ( !cff2 && fd_index.count > CFF_MAX_CID_FONTS )
+      /* TODO: support this for CFF2                */
+      if ( fd_index.count > CFF_MAX_CID_FONTS )
       {
         FT_TRACE0(( "cff_font_load: FD array too large in CID font\n" ));
         goto Fail_CID;
@@ -2134,7 +2151,7 @@ Exit:
         sub = font->subfonts[idx];
         FT_TRACE4(( "parsing subfont %u\n", idx ));
         error = cff_subfont_load( sub, &fd_index, idx,
-                                  stream, base_offset, library, 
+                                  stream, base_offset, library,
                                   cff2 ? CFF2_CODE_FONTDICT : CFF_CODE_TOPDICT,
                                   font );
         if ( error )
diff --git a/src/cff/cffparse.c b/src/cff/cffparse.c
index 8f54cb0..916d5f6 100644
--- a/src/cff/cffparse.c
+++ b/src/cff/cffparse.c
@@ -37,22 +37,48 @@
 #define FT_COMPONENT  trace_cffparse
 
 
-  FT_LOCAL_DEF( void )
+  FT_LOCAL_DEF( FT_Error )
   cff_parser_init( CFF_Parser  parser,
                    FT_UInt     code,
                    void*       object,
                    FT_Library  library,
+                   FT_UInt     stackSize,
                    FT_UShort   num_designs,
                    FT_UShort   num_axes )
   {
+    FT_Memory  memory = library->memory;    /* for FT_NEW_ARRAY */
+    FT_Error   error;                       /* for FT_NEW_ARRAY */
+
     FT_MEM_ZERO( parser, sizeof ( *parser ) );
 
-    parser->top         = parser->stack;
+    /*parser->top         = parser->stack;*/
     parser->object_code = code;
     parser->object      = object;
     parser->library     = library;
     parser->num_designs = num_designs;
     parser->num_axes    = num_axes;
+
+    /* allocate the stack buffer */
+    if ( FT_NEW_ARRAY( parser->stack, stackSize ) )
+    {
+      FT_FREE( parser->stack );
+      goto Exit;
+    }
+
+    parser->stackSize = stackSize;
+    parser->top = parser->stack;    /* empty stack */
+
+  Exit:
+    return error;
+  }
+
+
+  FT_LOCAL_DEF( void )
+  cff_parser_done( CFF_Parser parser )
+  {
+    FT_Memory  memory = parser->library->memory;    /* for FT_FREE */
+
+    FT_FREE( parser->stack );
   }
 
 
@@ -865,6 +891,36 @@
     return error;
   }
 
+  /* maxstack operator increases parser and operand stacks for CFF2 */
+  static FT_Error
+  cff_parse_maxstack( CFF_Parser  parser )
+  {
+    /* maxstack operator can only be used in a Top DICT */
+    CFF_FontRecDict  dict = (CFF_FontRecDict)parser->object;
+    FT_Byte**        data = parser->stack;
+    FT_Error         error = FT_Err_Ok;
+
+    if ( !dict )
+    {
+      error = FT_ERR( Invalid_File_Format );
+      goto Exit;
+    }
+
+    dict->maxstack = (FT_UInt)cff_parse_num( parser, data++ );
+    if ( dict->maxstack > CFF2_MAX_STACK )
+      dict->maxstack = CFF2_MAX_STACK;
+    if ( dict->maxstack < CFF2_DEFAULT_STACK )
+      dict->maxstack = CFF2_DEFAULT_STACK;
+
+    FT_TRACE4(( " %d\n", dict->maxstack ));
+    error = FT_Err_Ok;
+
+  Exit:
+    return error;
+  }
+
+
+
 #define CFF_FIELD_NUM( code, name, id )             \
           CFF_FIELD( code, name, id, cff_kind_num )
 #define CFF_FIELD_FIXED( code, name, id )             \
@@ -1171,7 +1227,7 @@
       if ( v >= 27 && v != 31 && v != 255 )
       {
         /* it's a number; we will push its position on the stack */
-        if ( parser->top - parser->stack >= CFF_MAX_STACK_DEPTH )
+        if ( (FT_UInt)( parser->top - parser->stack ) >= parser->stackSize )
           goto Stack_Overflow;
 
         *parser->top++ = p;
@@ -1262,7 +1318,7 @@
           FT_Bool   neg;
 
 
-          if ( parser->top - parser->stack >= CFF_MAX_STACK_DEPTH )
+          if ( parser->top - parser->stack >= parser->stackSize )*/
             goto Stack_Overflow;
 
           *parser->top++ = q;
diff --git a/src/cff/cffparse.h b/src/cff/cffparse.h
index 7c08015..f27d6c7 100644
--- a/src/cff/cffparse.h
+++ b/src/cff/cffparse.h
@@ -28,7 +28,11 @@
 FT_BEGIN_HEADER
 
 
-#define CFF_MAX_STACK_DEPTH  193
+/* CFF uses constant parser stack size */
+/* CFF2 can increase from default 193  */
+#define CFF_MAX_STACK_DEPTH     96
+#define CFF2_MAX_STACK          513
+#define CFF2_DEFAULT_STACK      193
 
 #define CFF_CODE_TOPDICT    0x1000
 #define CFF_CODE_PRIVATE    0x2000
@@ -44,8 +48,9 @@ FT_BEGIN_HEADER
     FT_Byte*    limit;
     FT_Byte*    cursor;
 
-    FT_Byte*    stack[CFF_MAX_STACK_DEPTH + 1];
+    FT_Byte**   stack;
     FT_Byte**   top;
+    FT_UInt     stackSize;  /* allocated size */
 
     FT_UInt     object_code;
     void*       object;
@@ -56,14 +61,18 @@ FT_BEGIN_HEADER
   } CFF_ParserRec, *CFF_Parser;
 
 
-  FT_LOCAL( void )
+  FT_LOCAL( FT_Error )
   cff_parser_init( CFF_Parser  parser,
                    FT_UInt     code,
                    void*       object,
                    FT_Library  library,
+                   FT_UInt     stackSize,
                    FT_UShort   num_designs,
                    FT_UShort   num_axes );
 
+  FT_LOCAL( void )
+  cff_parser_done( CFF_Parser  parser );
+
   FT_LOCAL( FT_Error )
   cff_parser_run( CFF_Parser  parser,
                   FT_Byte*    start,
diff --git a/src/cff/cfftoken.h b/src/cff/cfftoken.h
index f1cf336..ab2fcfd 100644
--- a/src/cff/cfftoken.h
+++ b/src/cff/cfftoken.h
@@ -107,12 +107,12 @@
 #undef  CFFCODE
 #define CFFCODE       CFF2_CODE_TOPDICT
 
-  CFF_FIELD_CALLBACK( 0x107, font_matrix,         "FontMatrix" )
-  CFF_FIELD_NUM     ( 17,    charstrings_offset,  "CharStrings" )
-  CFF_FIELD_NUM     ( 0x124, cid_fd_array_offset,  "FDArray" )
-  CFF_FIELD_NUM     ( 0x125, cid_fd_select_offset, "FDSelect" )
-  CFF_FIELD_NUM     ( 24,    vstore_offset,       "vstore" )
-  CFF_FIELD_NUM     ( 25,    maxstack,            "maxstack" )
+  CFF_FIELD_CALLBACK( 0x107, font_matrix,              "FontMatrix" )
+  CFF_FIELD_NUM     ( 17,    charstrings_offset,       "CharStrings" )
+  CFF_FIELD_NUM     ( 0x124, cid_fd_array_offset,      "FDArray" )
+  CFF_FIELD_NUM     ( 0x125, cid_fd_select_offset,     "FDSelect" )
+  CFF_FIELD_NUM     ( 24,    vstore_offset,            "vstore" )
+  CFF_FIELD_CALLBACK( 25,    maxstack,                 "maxstack" )
 
 #undef  FT_STRUCTURE
 #define FT_STRUCTURE  CFF_FontRecDictRec
@@ -120,9 +120,8 @@
 #undef  CFFCODE
 #define CFFCODE       CFF2_CODE_FONTDICT
 
-  CFF_FIELD_CALLBACK( 18,    private_dict,        "Private" )
-  CFF_FIELD_CALLBACK( 0x107, font_matrix,         "FontMatrix" )
-  CFF_FIELD_STRING  ( 0x126, cid_font_name,        "FontName" )
+  CFF_FIELD_CALLBACK( 18,    private_dict,             "Private" )
+  CFF_FIELD_CALLBACK( 0x107, font_matrix,              "FontMatrix" )
 
 #undef  FT_STRUCTURE
 #define FT_STRUCTURE  CFF_PrivateRec



reply via email to

[Prev in Thread] Current Thread [Next in Thread]