FT_Realloc( FT_Memory memory, FT_Long current, FT_Long size, void* *P ) { FT_Error error; (void)FT_REALLOC( *P, current, size ); return error; }
/* return false on memory error */ static FT_Bool cf2_arrstack_setNumElements( CF2_ArrStack arrstack, size_t numElements ) { FT_ASSERT( arrstack != NULL ); { FT_Error error = FT_Err_Ok; /* for FT_REALLOC */ FT_Memory memory = arrstack->memory; /* for FT_REALLOC */ FT_Long newSize = numElements * arrstack->sizeItem; if ( numElements > LONG_MAX / arrstack->sizeItem ) goto exit; FT_ASSERT( newSize > 0 ); /* avoid realloc with zero size */ if ( !FT_REALLOC( arrstack->ptr, arrstack->totalSize, newSize ) ) { arrstack->allocated = numElements; arrstack->totalSize = newSize; if ( arrstack->count > numElements ) { /* we truncated the list! */ CF2_SET_ERROR( arrstack->error, Stack_Overflow ); arrstack->count = numElements; return FALSE; } return TRUE; /* success */ } } exit: /* if there's not already an error, store this one */ CF2_SET_ERROR( arrstack->error, Out_Of_Memory ); return FALSE; }
/* Builds a table that maps Unicode values to glyph indices */ static FT_Error ps_unicodes_init( FT_Memory memory, FT_UInt num_glyphs, const char** glyph_names, PS_Unicodes* table ) { FT_Error error; /* we first allocate the table */ table->num_maps = 0; table->maps = 0; if ( !FT_NEW_ARRAY( table->maps, num_glyphs ) ) { FT_UInt n; FT_UInt count; PS_UniMap* map; FT_UInt32 uni_char; map = table->maps; for ( n = 0; n < num_glyphs; n++ ) { const char* gname = glyph_names[n]; if ( gname ) { uni_char = ps_unicode_value( gname ); if ( uni_char != 0 && uni_char != 0xFFFFL ) { map->unicode = (FT_UInt)uni_char; map->glyph_index = n; map++; } } } /* now, compress the table a bit */ count = (FT_UInt)( map - table->maps ); if ( count > 0 && FT_REALLOC( table->maps, num_glyphs * sizeof ( PS_UniMap ), count * sizeof ( PS_UniMap ) ) ) count = 0; if ( count == 0 ) { FT_FREE( table->maps ); if ( !error ) error = PSnames_Err_Invalid_Argument; /* no unicode chars here! */ } else /* sort the table in increasing order of unicode values */ ft_qsort( table->maps, count, sizeof ( PS_UniMap ), compare_uni_maps ); table->num_maps = count; } return error; }
static void t42_parse_sfnts( T42_Face face, T42_Loader loader ) { T42_Parser parser = &loader->parser; FT_Memory memory = parser->root.memory; FT_Byte* cur; FT_Byte* limit = parser->root.limit; FT_Error error; FT_Int num_tables = 0; FT_ULong count; FT_Long n, string_size, old_string_size, real_size; FT_Byte* string_buf = NULL; FT_Bool allocated = 0; T42_Load_Status status; /* The format is */ /* */ /* /sfnts [ <hexstring> <hexstring> ... ] def */ /* */ /* or */ /* */ /* /sfnts [ */ /* <num_bin_bytes> RD <binary data> */ /* <num_bin_bytes> RD <binary data> */ /* ... */ /* ] def */ /* */ /* with exactly one space after the `RD' token. */ T1_Skip_Spaces( parser ); if ( parser->root.cursor >= limit || *parser->root.cursor++ != '[' ) { FT_ERROR(( "t42_parse_sfnts: can't find begin of sfnts vector\n" )); error = FT_THROW( Invalid_File_Format ); goto Fail; } T1_Skip_Spaces( parser ); status = BEFORE_START; string_size = 0; old_string_size = 0; count = 0; while ( parser->root.cursor < limit ) { cur = parser->root.cursor; if ( *cur == ']' ) { parser->root.cursor++; goto Exit; } else if ( *cur == '<' ) { T1_Skip_PS_Token( parser ); if ( parser->root.error ) goto Exit; /* don't include delimiters */ string_size = (FT_Long)( ( parser->root.cursor - cur - 2 + 1 ) / 2 ); if ( !string_size ) { FT_ERROR(( "t42_parse_sfnts: invalid data in sfnts array\n" )); error = FT_THROW( Invalid_File_Format ); goto Fail; } if ( FT_REALLOC( string_buf, old_string_size, string_size ) ) goto Fail; allocated = 1; parser->root.cursor = cur; (void)T1_ToBytes( parser, string_buf, string_size, &real_size, 1 ); old_string_size = string_size; string_size = real_size; } else if ( ft_isdigit( *cur ) ) { if ( allocated ) { FT_ERROR(( "t42_parse_sfnts: " "can't handle mixed binary and hex strings\n" )); error = FT_THROW( Invalid_File_Format ); goto Fail; } string_size = T1_ToInt( parser ); if ( string_size < 0 ) { FT_ERROR(( "t42_parse_sfnts: invalid string size\n" )); error = FT_THROW( Invalid_File_Format ); goto Fail; } T1_Skip_PS_Token( parser ); /* `RD' */ if ( parser->root.error ) return; string_buf = parser->root.cursor + 1; /* one space after `RD' */ if ( limit - parser->root.cursor < string_size ) { FT_ERROR(( "t42_parse_sfnts: too much binary data\n" )); error = FT_THROW( Invalid_File_Format ); goto Fail; } else parser->root.cursor += string_size + 1; } if ( !string_buf ) { FT_ERROR(( "t42_parse_sfnts: invalid data in sfnts array\n" )); error = FT_THROW( Invalid_File_Format ); goto Fail; } /* A string can have a trailing zero (odd) byte for padding. */ /* Ignore it. */ if ( ( string_size & 1 ) && string_buf[string_size - 1] == 0 ) string_size--; if ( !string_size ) { FT_ERROR(( "t42_parse_sfnts: invalid string\n" )); error = FT_THROW( Invalid_File_Format ); goto Fail; } for ( n = 0; n < string_size; n++ ) { switch ( status ) { case BEFORE_START: /* load offset table, 12 bytes */ if ( count < 12 ) { face->ttf_data[count++] = string_buf[n]; continue; } else { num_tables = 16 * face->ttf_data[4] + face->ttf_data[5]; status = BEFORE_TABLE_DIR; face->ttf_size = 12 + 16 * num_tables; if ( (FT_ULong)( limit - parser->root.cursor ) < face->ttf_size ) { FT_ERROR(( "t42_parse_sfnts: invalid data in sfnts array\n" )); error = FT_THROW( Invalid_File_Format ); goto Fail; } if ( FT_REALLOC( face->ttf_data, 12, face->ttf_size ) ) goto Fail; } /* fall through */ case BEFORE_TABLE_DIR: /* the offset table is read; read the table directory */ if ( count < face->ttf_size ) { face->ttf_data[count++] = string_buf[n]; continue; } else { int i; FT_ULong len; for ( i = 0; i < num_tables; i++ ) { FT_Byte* p = face->ttf_data + 12 + 16 * i + 12; len = FT_PEEK_ULONG( p ); /* Pad to a 4-byte boundary length */ face->ttf_size += ( len + 3 ) & ~3; } status = OTHER_TABLES; /* there are no more than 256 tables, so no size check here */ if ( FT_REALLOC( face->ttf_data, 12 + 16 * num_tables, face->ttf_size + 1 ) ) goto Fail; } /* fall through */ case OTHER_TABLES: /* all other tables are just copied */ if ( count >= face->ttf_size ) { FT_ERROR(( "t42_parse_sfnts: too much binary data\n" )); error = FT_THROW( Invalid_File_Format ); goto Fail; } face->ttf_data[count++] = string_buf[n]; } } T1_Skip_Spaces( parser ); } /* if control reaches this point, the format was not valid */ error = FT_THROW( Invalid_File_Format ); Fail: parser->root.error = error; Exit: if ( allocated ) FT_FREE( string_buf ); }