< 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 >