static FT_Error cff_index_load_offsets( CFF_Index idx ) { FT_Error error = 0; FT_Stream stream = idx->stream; FT_Memory memory = stream->memory; if ( idx->count > 0 && idx->offsets == NULL ) { FT_Byte offsize = idx->off_size; FT_ULong data_size; FT_Byte* p; FT_Byte* p_end; FT_ULong* poff; data_size = (FT_ULong)( idx->count + 1 ) * offsize; if ( FT_NEW_ARRAY( idx->offsets, idx->count + 1 ) || FT_STREAM_SEEK( idx->start + 3 ) || FT_FRAME_ENTER( data_size ) ) goto Exit; poff = idx->offsets; p = (FT_Byte*)stream->cursor; p_end = p + data_size; switch ( offsize ) { case 1: for ( ; p < p_end; p++, poff++ ) poff[0] = p[0]; break; case 2: for ( ; p < p_end; p += 2, poff++ ) poff[0] = FT_PEEK_USHORT( p ); break; case 3: for ( ; p < p_end; p += 3, poff++ ) poff[0] = FT_PEEK_OFF3( p ); break; default: for ( ; p < p_end; p += 4, poff++ ) poff[0] = FT_PEEK_ULONG( p ); } FT_FRAME_EXIT(); } Exit: if ( error ) FT_FREE( idx->offsets ); return error; }
tt_face_find_bdf_prop( TT_Face face, const char* property_name, BDF_PropertyRec *aprop ) { TT_BDF bdf = &face->bdf; FT_Size size = FT_FACE(face)->size; FT_Error error = FT_Err_Ok; FT_Byte* p; FT_UInt count; FT_Byte* strike; FT_Offset property_len; aprop->type = BDF_PROPERTY_TYPE_NONE; if ( bdf->loaded == 0 ) { error = tt_face_load_bdf_props( face, FT_FACE( face )->stream ); if ( error ) goto Exit; } count = bdf->num_strikes; p = bdf->table + 8; strike = p + 4 * count; error = FT_ERR( Invalid_Argument ); if ( size == NULL || property_name == NULL ) goto Exit; property_len = ft_strlen( property_name ); if ( property_len == 0 ) goto Exit; for ( ; count > 0; count-- ) { FT_UInt _ppem = FT_NEXT_USHORT( p ); FT_UInt _count = FT_NEXT_USHORT( p ); if ( _ppem == size->metrics.y_ppem ) { count = _count; goto FoundStrike; } strike += 10 * _count; } goto Exit; FoundStrike: p = strike; for ( ; count > 0; count-- ) { FT_UInt type = FT_PEEK_USHORT( p + 4 ); if ( ( type & 0x10 ) != 0 ) { FT_UInt32 name_offset = FT_PEEK_ULONG( p ); FT_UInt32 value = FT_PEEK_ULONG( p + 6 ); /* be a bit paranoid for invalid entries here */ if ( name_offset < bdf->strings_size && property_len < bdf->strings_size - name_offset && ft_strncmp( property_name, (const char*)bdf->strings + name_offset, bdf->strings_size - name_offset ) == 0 ) { switch ( type & 0x0F ) { case 0x00: /* string */ case 0x01: /* atoms */ /* check that the content is really 0-terminated */ if ( value < bdf->strings_size && ft_memchr( bdf->strings + value, 0, bdf->strings_size ) ) { aprop->type = BDF_PROPERTY_TYPE_ATOM; aprop->u.atom = (const char*)bdf->strings + value; error = FT_Err_Ok; goto Exit; } break; case 0x02: aprop->type = BDF_PROPERTY_TYPE_INTEGER; aprop->u.integer = (FT_Int32)value; error = FT_Err_Ok; goto Exit; case 0x03: aprop->type = BDF_PROPERTY_TYPE_CARDINAL; aprop->u.cardinal = value; error = FT_Err_Ok; goto Exit; default: ; } } } p += 10; } Exit: 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 ); }