/* * TODO: length should be limit? **/ static void gxv_morx_subtable_type1_substitutionTable_validate( FT_Bytes table, FT_Bytes limit, GXV_Validator valid ) { FT_Bytes p = table; FT_UShort i; GXV_morx_subtable_type1_StateOptRecData optdata = (GXV_morx_subtable_type1_StateOptRecData)valid->xstatetable.optdata; /* TODO: calculate offset/length for each lookupTables */ valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; valid->lookupval_func = gxv_morx_subtable_type1_LookupValue_validate; valid->lookupfmt4_trans = gxv_morx_subtable_type1_LookupFmt4_transit; for ( i = 0; i < optdata->substitutionTable_num_lookupTables; i++ ) { FT_ULong offset; GXV_LIMIT_CHECK( 4 ); offset = FT_NEXT_ULONG( p ); gxv_LookupTable_validate( table + offset, limit, valid ); } /* TODO: overlapping of lookupTables in substitutionTable */ }
gxv_opbd_validate( FT_Bytes table, FT_Face face, FT_Validator ftvalid ) { GXV_ValidatorRec gxvalidrec; GXV_Validator gxvalid = &gxvalidrec; GXV_opbd_DataRec opbdrec; GXV_opbd_Data opbd = &opbdrec; FT_Bytes p = table; FT_Bytes limit = 0; FT_ULong version; gxvalid->root = ftvalid; gxvalid->table_data = opbd; gxvalid->face = face; FT_TRACE3(( "validating `opbd' table\n" )); GXV_INIT; GXV_OPBD_DATA( valueOffset_min ) = 0xFFFFU; GXV_LIMIT_CHECK( 4 + 2 ); version = FT_NEXT_ULONG( p ); GXV_OPBD_DATA( format ) = FT_NEXT_USHORT( p ); /* only 0x00010000 is defined (1996) */ GXV_TRACE(( "(version=0x%08x)\n", version )); if ( 0x00010000UL != version ) FT_INVALID_FORMAT; /* only values 0 and 1 are defined (1996) */ GXV_TRACE(( "(format=0x%04x)\n", GXV_OPBD_DATA( format ) )); if ( 0x0001 < GXV_OPBD_DATA( format ) ) FT_INVALID_FORMAT; gxvalid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; gxvalid->lookupval_func = gxv_opbd_LookupValue_validate; gxvalid->lookupfmt4_trans = gxv_opbd_LookupFmt4_transit; gxv_LookupTable_validate( p, limit, gxvalid ); p += gxvalid->subtable_length; if ( p > table + GXV_OPBD_DATA( valueOffset_min ) ) { GXV_TRACE(( "found overlap between LookupTable and opbd_value array\n" )); FT_INVALID_OFFSET; } FT_TRACE4(( "\n" )); }
gxv_mort_subtable_type4_validate( FT_Bytes table, FT_Bytes limit, GXV_Validator gxvalid ) { FT_Bytes p = table; GXV_NAME_ENTER( "mort chain subtable type4 " "(Non-Contextual Glyph Substitution)" ); gxvalid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; gxvalid->lookupval_func = gxv_mort_subtable_type4_lookupval_validate; gxvalid->lookupfmt4_trans = gxv_mort_subtable_type4_lookupfmt4_transit; gxv_LookupTable_validate( p, limit, gxvalid ); GXV_EXIT; }
static void gxv_just_justData_lookuptable_validate( FT_Bytes table, FT_Bytes limit, GXV_Validator valid ) { FT_Bytes p = table; GXV_JUST_DATA( wdc_offset_max ) = 0x0000; GXV_JUST_DATA( wdc_offset_min ) = 0xFFFFU; valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; valid->lookupval_func = gxv_just_wdcTable_LookupValue_validate; gxv_LookupTable_validate( p, limit, valid ); /* subtable_length is set by gxv_LookupTable_validate() */ GXV_EXIT; }
static void gxv_just_pcLookupTable_validate( FT_Bytes table, FT_Bytes limit, GXV_Validator gxvalid ) { FT_Bytes p = table; GXV_NAME_ENTER( "just pcLookupTable" ); GXV_JUST_DATA( pc_offset_max ) = 0x0000; GXV_JUST_DATA( pc_offset_min ) = 0xFFFFU; gxvalid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; gxvalid->lookupval_func = gxv_just_pcTable_LookupValue_entry_validate; gxv_LookupTable_validate( p, limit, gxvalid ); /* subtable_length is set by gxv_LookupTable_validate() */ GXV_EXIT; }
gxv_lcar_validate( FT_Bytes table, FT_Face face, FT_Validator ftvalid ) { FT_Bytes p = table; FT_Bytes limit = 0; GXV_ValidatorRec validrec; GXV_Validator valid = &validrec; GXV_lcar_DataRec lcarrec; GXV_lcar_Data lcar = &lcarrec; FT_Fixed version; valid->root = ftvalid; valid->table_data = lcar; valid->face = face; FT_TRACE3(( "validating `lcar' table\n" )); GXV_INIT; GXV_LIMIT_CHECK( 4 + 2 ); version = FT_NEXT_ULONG( p ); GXV_LCAR_DATA( format ) = FT_NEXT_USHORT( p ); if ( version != 0x00010000UL) FT_INVALID_FORMAT; if ( GXV_LCAR_DATA( format ) > 1 ) FT_INVALID_FORMAT; valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; valid->lookupval_func = gxv_lcar_LookupValue_validate; valid->lookupfmt4_trans = gxv_lcar_LookupFmt4_transit; gxv_LookupTable_validate( p, limit, valid ); FT_TRACE4(( "\n" )); }
static void gxv_bsln_parts_fmt3_validate( FT_Bytes tables, FT_Bytes limit, GXV_Validator valid) { FT_Bytes p = tables; GXV_NAME_ENTER( "parts format 3" ); /* stdGlyph + ctlPoints */ gxv_bsln_parts_fmt2_validate( p, limit, valid ); /* mappingData */ valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; valid->lookupval_func = gxv_bsln_LookupValue_validate; valid->lookupfmt4_trans = gxv_bsln_LookupFmt4_transit; gxv_LookupTable_validate( p + ( 2 + 2 * GXV_BSLN_VALUE_COUNT ), limit, valid ); GXV_EXIT; }
static void gxv_bsln_parts_fmt1_validate( FT_Bytes tables, FT_Bytes limit, GXV_Validator gxvalid ) { FT_Bytes p = tables; GXV_NAME_ENTER( "parts format 1" ); /* deltas */ gxv_bsln_parts_fmt0_validate( p, limit, gxvalid ); /* mappingData */ gxvalid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; gxvalid->lookupval_func = gxv_bsln_LookupValue_validate; gxvalid->lookupfmt4_trans = gxv_bsln_LookupFmt4_transit; gxv_LookupTable_validate( p + 2 * GXV_BSLN_VALUE_COUNT, limit, gxvalid ); GXV_EXIT; }