summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Arnold <darnold@adobe.com>2016-11-16 14:57:52 -0800
committerDave Arnold <darnold@adobe.com>2016-11-16 14:57:52 -0800
commit88ad21fbe54a5bad1d169e127094e26f1f840fba (patch)
tree95067cd732c415e8673a4d53966627f533b51a73
parentd49da66dcb60b0b11673eb42fa89de1bc6a20c8c (diff)
downloadfreetype2-88ad21fbe54a5bad1d169e127094e26f1f840fba.tar.gz
[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().
-rw-r--r--src/cff/cf2intrp.c9
-rw-r--r--src/cff/cffload.c39
-rw-r--r--src/cff/cffparse.c64
-rw-r--r--src/cff/cffparse.h15
-rw-r--r--src/cff/cfftoken.h17
5 files changed, 110 insertions, 34 deletions
diff --git a/src/cff/cf2intrp.c b/src/cff/cf2intrp.c
index 9b190775a..66a237111 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 4c65c94e6..1a6454314 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 8f54cb0e6..916d5f648 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 7c0801596..f27d6c7f7 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 f1cf3364a..ab2fcfd6b 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