ref: 642bc7590c701c8cd35a9f60fa899cfa518b17ff
parent: 81f43a9d36c977beadc8ece0b28ba13ba86484ba
author: Armin Hasitzka <[email protected]>
date: Thu Nov 22 05:29:35 EST 2018
[cff] Fix memory overflow. Reported as https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9869 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10869 * src/cff/cffparse.c (destruct_t2s_item, cff_parser_run): Store evaluated T2 charstrings in separately allocated memory.
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2018-11-22 Armin Hasitzka <[email protected]>
+
+ [cff] Fix memory overflow.
+
+ Reported as
+
+ https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=9869
+ https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10869
+
+ * src/cff/cffparse.c (destruct_t2s_item, cff_parser_run): Store
+ evaluated T2 charstrings in separately allocated memory.
+
2018-11-18 Alexei Podtelezhnikov <[email protected]>
* builds/windows/{visualc,vc2005,vc2008}/freetype.vcproj: Fix it.
--- a/src/cff/cffparse.c
+++ b/src/cff/cffparse.c
@@ -1121,22 +1121,36 @@
#endif /* FT_DEBUG_LEVEL_TRACE */
+ static void
+ destruct_t2s_item( FT_Memory memory,
+ void* data,
+ void* user )
+ {
+ FT_UNUSED( user );
+ memory->free( memory, data );
+ }
+
+
FT_LOCAL_DEF( FT_Error )
cff_parser_run( CFF_Parser parser,
FT_Byte* start,
FT_Byte* limit )
{
+ FT_Byte* p = start;
+ FT_Error error = FT_Err_Ok;
+
#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
PSAux_Service psaux;
-#endif
- FT_Byte* p = start;
- FT_Error error = FT_Err_Ok;
FT_Library library = parser->library;
+ FT_Memory memory = library->memory;
- FT_UNUSED( library );
+ FT_ListRec t2s;
+ FT_ZERO( &t2s );
+#endif
+
parser->top = parser->stack;
parser->start = start;
parser->limit = limit;
@@ -1195,8 +1209,9 @@
FT_Byte* charstring_base;
FT_ULong charstring_len;
- FT_Fixed* stack;
- FT_Byte* q;
+ FT_Fixed* stack;
+ FT_ListNode node;
+ FT_Byte* q;
charstring_base = ++p;
@@ -1237,13 +1252,23 @@
/* Now copy the stack data in the temporary decoder object, */
/* converting it back to charstring number representations */
/* (this is ugly, I know). */
- /* */
- /* We overwrite the original top DICT charstring under the */
- /* assumption that the charstring representation of the result */
- /* of `cff_decoder_parse_charstrings' is shorter, which should */
- /* be always true. */
- q = charstring_base - 1;
+ node = (FT_ListNode)memory->alloc( memory,
+ sizeof ( FT_ListNodeRec ) );
+ if ( !node )
+ goto Out_Of_Memory_Error;
+
+ /* `5' is the conservative upper bound of required bytes per stack */
+ /* element. */
+ q = (FT_Byte*)memory->alloc( memory,
+ 5 * ( decoder.top - decoder.stack ) );
+ if ( !q )
+ goto Out_Of_Memory_Error;
+
+ node->data = q;
+
+ FT_List_Add( &t2s, node );
+
stack = decoder.stack;
while ( stack < decoder.top )
@@ -1500,10 +1525,17 @@
parser->top = parser->stack;
}
p++;
- }
+ } /* while ( p < limit ) */
Exit:
+#ifdef CFF_CONFIG_OPTION_OLD_ENGINE
+ FT_List_Finalize( &t2s, destruct_t2s_item, memory, NULL );
+#endif
return error;
+
+ Out_Of_Memory_Error:
+ error = FT_THROW( Out_Of_Memory );
+ goto Exit;
Stack_Overflow:
error = FT_THROW( Invalid_Argument );