static void gxv_mort_subtable_type1_substTable_validate( FT_Bytes table, FT_Bytes limit, GXV_Validator valid ) { FT_Bytes p = table; FT_UShort num_gids = (FT_UShort)( ((GXV_mort_subtable_type1_StateOptRec *) (valid->statetable.optdata))->substitutionTable_length / 2 ); FT_UShort i; GXV_NAME_ENTER( "validating contents of substitutionTable" ); for ( i = 0; i < num_gids ; i ++ ) { FT_UShort dst_gid; GXV_LIMIT_CHECK( 2 ); dst_gid = FT_NEXT_USHORT( p ); if ( dst_gid >= 0xFFFFU ) continue; if ( dst_gid < valid->min_gid || valid->max_gid < dst_gid ) { GXV_TRACE(( "substTable include a strange gid[%d]=%d >" " out of define range (%d..%d)\n", i, dst_gid, valid->min_gid, valid->max_gid )); GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); } } GXV_EXIT; }
static void gxv_morx_chain_validate( FT_Bytes table, FT_Bytes limit, GXV_Validator valid ) { FT_Bytes p = table; FT_ULong defaultFlags; FT_ULong chainLength; FT_ULong nFeatureFlags; FT_ULong nSubtables; GXV_NAME_ENTER( "morx chain header" ); GXV_LIMIT_CHECK( 4 + 4 + 4 + 4 ); defaultFlags = FT_NEXT_ULONG( p ); chainLength = FT_NEXT_ULONG( p ); nFeatureFlags = FT_NEXT_ULONG( p ); nSubtables = FT_NEXT_ULONG( p ); /* feature-array of morx is same with that of mort */ gxv_mort_featurearray_validate( p, limit, nFeatureFlags, valid ); p += valid->subtable_length; if ( nSubtables >= 0x10000L ) FT_INVALID_DATA; gxv_morx_subtables_validate( p, table + chainLength, (FT_UShort)nSubtables, valid ); valid->subtable_length = chainLength; GXV_EXIT; }
static void gxv_morx_subtable_type2_ligatureTable_validate( FT_Bytes table, GXV_Validator gxvalid ) { GXV_morx_subtable_type2_StateOptRecData optdata = (GXV_morx_subtable_type2_StateOptRecData)gxvalid->xstatetable.optdata; FT_Bytes p = table + optdata->ligatureTable; FT_Bytes limit = table + optdata->ligatureTable + optdata->ligatureTable_length; GXV_NAME_ENTER( "morx chain subtable type2 - substitutionTable" ); if ( 0 != optdata->ligatureTable ) { /* Apple does not give specification of ligatureTable format */ while ( p < limit ) { FT_UShort lig_gid; GXV_LIMIT_CHECK( 2 ); lig_gid = FT_NEXT_USHORT( p ); if ( lig_gid < gxvalid->face->num_glyphs ) GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID ); } } GXV_EXIT; }
gxv_morx_subtable_type1_validate( FT_Bytes table, FT_Bytes limit, GXV_Validator valid ) { FT_Bytes p = table; GXV_morx_subtable_type1_StateOptRec st_rec; GXV_NAME_ENTER( "morx chain subtable type1 (Contextual Glyph Subst)" ); GXV_LIMIT_CHECK( GXV_MORX_SUBTABLE_TYPE1_HEADER_SIZE ); st_rec.substitutionTable_num_lookupTables = 0; valid->xstatetable.optdata = &st_rec; valid->xstatetable.optdata_load_func = gxv_morx_subtable_type1_substitutionTable_load; valid->xstatetable.subtable_setup_func = gxv_morx_subtable_type1_subtable_setup; valid->xstatetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_ULONG; valid->xstatetable.entry_validate_func = gxv_morx_subtable_type1_entry_validate; gxv_XStateTable_validate( p, limit, valid ); gxv_morx_subtable_type1_substitutionTable_validate( table + st_rec.substitutionTable, table + st_rec.substitutionTable + st_rec.substitutionTable_length, valid ); GXV_EXIT; }
gxv_mort_subtable_type5_validate( FT_Bytes table, FT_Bytes limit, GXV_Validator gxvalid ) { FT_Bytes p = table; GXV_mort_subtable_type5_StateOptRec et_rec; GXV_mort_subtable_type5_StateOptRecData et = &et_rec; GXV_NAME_ENTER( "mort chain subtable type5 (Glyph Insertion)" ); GXV_LIMIT_CHECK( GXV_MORT_SUBTABLE_TYPE5_HEADER_SIZE ); gxvalid->statetable.optdata = et; gxvalid->statetable.optdata_load_func = NULL; gxvalid->statetable.subtable_setup_func = gxv_mort_subtable_type5_subtable_setup; gxvalid->statetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_ULONG; gxvalid->statetable.entry_validate_func = gxv_mort_subtable_type5_entry_validate; gxv_StateTable_validate( p, limit, gxvalid ); GXV_EXIT; }
static void gxv_feat_setting_validate( FT_Bytes table, FT_Bytes limit, FT_Bool exclusive, GXV_Validator valid ) { FT_Bytes p = table; FT_UShort setting; GXV_NAME_ENTER( "setting" ); GXV_LIMIT_CHECK( 2 ); setting = FT_NEXT_USHORT( p ); /* If we have exclusive setting, the setting should be odd. */ if ( exclusive && ( setting % 2 ) == 0 ) FT_INVALID_DATA; gxv_feat_name_index_validate( p, limit, valid ); GXV_FEAT_DATA( setting ) = setting; GXV_EXIT; }
gxv_mort_featurearray_validate( FT_Bytes table, FT_Bytes limit, FT_ULong nFeatureFlags, GXV_Validator valid ) { FT_Bytes p = table; FT_ULong i; GXV_mort_featureRec f = GXV_MORT_FEATURE_OFF; GXV_NAME_ENTER( "mort feature list" ); for ( i = 0; i < nFeatureFlags; i++ ) { GXV_LIMIT_CHECK( 2 + 2 + 4 + 4 ); f.featureType = FT_NEXT_USHORT( p ); f.featureSetting = FT_NEXT_USHORT( p ); f.enableFlags = FT_NEXT_ULONG( p ); f.disableFlags = FT_NEXT_ULONG( p ); gxv_mort_feature_validate( &f, valid ); } if ( !IS_GXV_MORT_FEATURE_OFF( f ) ) FT_INVALID_DATA; valid->subtable_length = p - table; GXV_EXIT; }
static void gxv_mort_chain_validate( FT_Bytes table, FT_Bytes limit, GXV_Validator gxvalid ) { FT_Bytes p = table; #ifdef GXV_LOAD_UNUSED_VARS FT_ULong defaultFlags; #endif FT_ULong chainLength; FT_UShort nFeatureFlags; FT_UShort nSubtables; GXV_NAME_ENTER( "mort chain header" ); GXV_LIMIT_CHECK( 4 + 4 + 2 + 2 ); #ifdef GXV_LOAD_UNUSED_VARS defaultFlags = FT_NEXT_ULONG( p ); #else p += 4; #endif chainLength = FT_NEXT_ULONG( p ); nFeatureFlags = FT_NEXT_USHORT( p ); nSubtables = FT_NEXT_USHORT( p ); gxv_mort_featurearray_validate( p, table + chainLength, nFeatureFlags, gxvalid ); p += gxvalid->subtable_length; gxv_mort_subtables_validate( p, table + chainLength, nSubtables, gxvalid ); gxvalid->subtable_length = chainLength; /* TODO: validate defaultFlags */ GXV_EXIT; }
static void gxv_mort_chain_validate( FT_Bytes table, FT_Bytes limit, GXV_Validator valid ) { FT_Bytes p = table; FT_ULong defaultFlags; FT_ULong chainLength; FT_UShort nFeatureFlags; FT_UShort nSubtables; GXV_NAME_ENTER( "mort chain header" ); GXV_LIMIT_CHECK( 4 + 4 + 2 + 2 ); defaultFlags = FT_NEXT_ULONG( p ); chainLength = FT_NEXT_ULONG( p ); nFeatureFlags = FT_NEXT_USHORT( p ); nSubtables = FT_NEXT_USHORT( p ); gxv_mort_featurearray_validate( p, table + chainLength, nFeatureFlags, valid ); p += valid->subtable_length; gxv_mort_subtables_validate( p, table + chainLength, nSubtables, valid ); valid->subtable_length = chainLength; GXV_EXIT; }
static void gxv_just_actSubrecord_type4_validate( FT_Bytes table, FT_Bytes limit, GXV_Validator gxvalid ) { FT_Bytes p = table; FT_ULong variantsAxis; FT_Fixed minimumLimit; FT_Fixed noStretchValue; FT_Fixed maximumLimit; GXV_LIMIT_CHECK( 4 + 4 + 4 + 4 ); variantsAxis = FT_NEXT_ULONG( p ); minimumLimit = FT_NEXT_ULONG( p ); noStretchValue = FT_NEXT_ULONG( p ); maximumLimit = FT_NEXT_ULONG( p ); gxvalid->subtable_length = p - table; if ( variantsAxis != 0x64756374L ) /* 'duct' */ GXV_TRACE(( "variantsAxis 0x%08x is non default value", variantsAxis )); if ( minimumLimit > noStretchValue ) GXV_TRACE(( "type4:minimumLimit 0x%08x > noStretchValue 0x%08x\n", minimumLimit, noStretchValue )); else if ( noStretchValue > maximumLimit ) GXV_TRACE(( "type4:noStretchValue 0x%08x > maximumLimit 0x%08x\n", noStretchValue, maximumLimit )); else if ( !IS_PARANOID_VALIDATION ) return; FT_INVALID_DATA; }
gxv_morx_subtable_type2_validate( FT_Bytes table, FT_Bytes limit, GXV_Validator gxvalid ) { FT_Bytes p = table; GXV_morx_subtable_type2_StateOptRec lig_rec; GXV_NAME_ENTER( "morx chain subtable type2 (Ligature Substitution)" ); GXV_LIMIT_CHECK( GXV_MORX_SUBTABLE_TYPE2_HEADER_SIZE ); gxvalid->xstatetable.optdata = &lig_rec; gxvalid->xstatetable.optdata_load_func = gxv_morx_subtable_type2_opttable_load; gxvalid->xstatetable.subtable_setup_func = gxv_morx_subtable_type2_subtable_setup; gxvalid->xstatetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_USHORT; gxvalid->xstatetable.entry_validate_func = gxv_morx_subtable_type2_entry_validate; gxv_XStateTable_validate( p, limit, gxvalid ); #if 0 p += gxvalid->subtable_length; #endif gxv_morx_subtable_type2_ligatureTable_validate( table, gxvalid ); GXV_EXIT; }
static void gxv_opbd_LookupValue_validate( FT_UShort glyph, GXV_LookupValueCPtr value_p, GXV_Validator valid ) { /* offset in LookupTable is measured from the head of opbd table */ FT_Bytes p = valid->root->base + value_p->u; FT_Bytes limit = valid->root->limit; FT_Short delta_value; int i; if ( value_p->u < GXV_OPBD_DATA( valueOffset_min ) ) GXV_OPBD_DATA( valueOffset_min ) = value_p->u; for ( i = 0; i < 4; i++ ) { GXV_LIMIT_CHECK( 2 ); delta_value = FT_NEXT_SHORT( p ); if ( GXV_OPBD_DATA( format ) ) /* format 1, value is ctrl pt. */ { if ( delta_value == -1 ) continue; gxv_ctlPoint_validate( glyph, delta_value, valid ); } else /* format 0, value is distance */ continue; } }
static void gxv_just_justClassTable_validate ( FT_Bytes table, FT_Bytes limit, GXV_Validator valid ) { FT_Bytes p = table; FT_UShort length; FT_UShort coverage; FT_ULong subFeatureFlags; GXV_NAME_ENTER( "just justClassTable" ); GXV_LIMIT_CHECK( 2 + 2 + 4 ); length = FT_NEXT_USHORT( p ); coverage = FT_NEXT_USHORT( p ); subFeatureFlags = FT_NEXT_ULONG( p ); GXV_TRACE(( " justClassTable: coverage = 0x%04x (%s)", coverage, ( 0x4000 & coverage ) == 0 ? "ascending" : "descending" )); valid->statetable.optdata = NULL; valid->statetable.optdata_load_func = NULL; valid->statetable.subtable_setup_func = NULL; valid->statetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_NONE; valid->statetable.entry_validate_func = gxv_just_classTable_entry_validate; gxv_StateTable_validate( p, table + length, valid ); /* subtable_length is set by gxv_LookupTable_validate() */ GXV_EXIT; }
static void gxv_mort_subtable_type2_ligatureTable_validate( FT_Bytes table, GXV_Validator valid ) { GXV_mort_subtable_type2_StateOptRecData optdata = (GXV_mort_subtable_type2_StateOptRecData)valid->statetable.optdata; FT_Bytes p = table + optdata->ligatureTable; FT_Bytes limit = table + optdata->ligatureTable + optdata->ligatureTable_length; GXV_NAME_ENTER( "mort chain subtable type2 - substitutionTable" ); if ( 0 != optdata->ligatureTable ) { /* Apple does not give specification of ligatureTable format */ while ( p < limit ) { FT_UShort lig_gid; GXV_LIMIT_CHECK( 2 ); lig_gid = FT_NEXT_USHORT( p ); } } GXV_EXIT; }
gxv_mort_subtable_type2_validate( FT_Bytes table, FT_Bytes limit, GXV_Validator valid ) { FT_Bytes p = table; GXV_mort_subtable_type2_StateOptRec lig_rec; GXV_NAME_ENTER( "mort chain subtable type2 (Ligature Substitution)" ); GXV_LIMIT_CHECK( GXV_MORT_SUBTABLE_TYPE2_HEADER_SIZE ); valid->statetable.optdata = &lig_rec; valid->statetable.optdata_load_func = gxv_mort_subtable_type2_opttable_load; valid->statetable.subtable_setup_func = gxv_mort_subtable_type2_subtable_setup; valid->statetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_NONE; valid->statetable.entry_validate_func = gxv_mort_subtable_type2_entry_validate; gxv_StateTable_validate( p, limit, valid ); p += valid->subtable_length; gxv_mort_subtable_type2_ligatureTable_validate( table, valid ); valid->subtable_length = p - table; GXV_EXIT; }
static void gxv_kern_subtable_fmt2_clstbl_validate( FT_Bytes table, FT_Bytes limit, GXV_kern_ClassSpec spec, GXV_Validator valid ) { const FT_String* tag = GXV_KERN_FMT2_DATA( class_tag[spec] ); GXV_odtect_Range odtect = GXV_KERN_FMT2_DATA( odtect ); FT_Bytes p = table; FT_UShort firstGlyph; FT_UShort nGlyphs; GXV_NAME_ENTER( "kern format 2 classTable" ); GXV_LIMIT_CHECK( 2 + 2 ); firstGlyph = FT_NEXT_USHORT( p ); nGlyphs = FT_NEXT_USHORT( p ); GXV_TRACE(( " %s firstGlyph=%d, nGlyphs=%d\n", tag, firstGlyph, nGlyphs )); gxv_glyphid_validate( firstGlyph, valid ); gxv_glyphid_validate( (FT_UShort)( firstGlyph + nGlyphs - 1 ), valid ); gxv_array_getlimits_ushort( p, p + ( 2 * nGlyphs ), &( GXV_KERN_FMT2_DATA( offset_min[spec] ) ), &( GXV_KERN_FMT2_DATA( offset_max[spec] ) ), valid ); gxv_odtect_add_range( table, 2 * nGlyphs, tag, odtect ); GXV_EXIT; }
static void gxv_kern_subtable_fmt0_validate( FT_Bytes table, FT_Bytes limit, GXV_Validator valid ) { FT_Bytes p = table + GXV_KERN_SUBTABLE_HEADER_SIZE; FT_UShort nPairs; FT_UShort unitSize; GXV_NAME_ENTER( "kern subtable format 0" ); unitSize = 2 + 2 + 2; nPairs = 0; /* nPairs, searchRange, entrySelector, rangeShift */ GXV_LIMIT_CHECK( 2 + 2 + 2 + 2 ); gxv_BinSrchHeader_validate( p, limit, &unitSize, &nPairs, valid ); p += 2 + 2 + 2 + 2; gxv_kern_subtable_fmt0_pairs_validate( p, limit, nPairs, valid ); GXV_EXIT; }
static void gxv_just_wdp_entry_validate( FT_Bytes table, FT_Bytes limit, GXV_Validator valid ) { FT_Bytes p = table; FT_ULong justClass; FT_Fixed beforeGrowLimit; FT_Fixed beforeShrinkGrowLimit; FT_Fixed afterGrowLimit; FT_Fixed afterShrinkGrowLimit; FT_UShort growFlags; FT_UShort shrinkFlags; GXV_LIMIT_CHECK( 4 + 4 + 4 + 4 + 4 + 2 + 2 ); justClass = FT_NEXT_ULONG( p ); beforeGrowLimit = FT_NEXT_ULONG( p ); beforeShrinkGrowLimit = FT_NEXT_ULONG( p ); afterGrowLimit = FT_NEXT_ULONG( p ); afterShrinkGrowLimit = FT_NEXT_ULONG( p ); growFlags = FT_NEXT_USHORT( p ); shrinkFlags = FT_NEXT_USHORT( p ); /* TODO: decode flags for human readability */ valid->subtable_length = p - table; }
/* * 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 */ }
static void gxv_just_actSubrecord_type2_validate( FT_Bytes table, FT_Bytes limit, GXV_Validator gxvalid ) { FT_Bytes p = table; #ifdef GXV_LOAD_UNUSED_VARS FT_Fixed substThreshhold; /* Apple misspelled "Threshhold" */ #endif FT_UShort addGlyph; FT_UShort substGlyph; GXV_LIMIT_CHECK( 4 + 2 + 2 ); #ifdef GXV_LOAD_UNUSED_VARS substThreshhold = FT_NEXT_ULONG( p ); #else p += 4; #endif addGlyph = FT_NEXT_USHORT( p ); substGlyph = FT_NEXT_USHORT( p ); if ( addGlyph != 0xFFFF ) gxv_just_check_max_gid( addGlyph, "type2:addGlyph", gxvalid ); gxv_just_check_max_gid( substGlyph, "type2:substGlyph", gxvalid ); gxvalid->subtable_length = p - table; }
static void gxv_just_actSubrecord_type0_validate( FT_Bytes table, FT_Bytes limit, GXV_Validator gxvalid ) { FT_Bytes p = table; FT_Fixed lowerLimit; FT_Fixed upperLimit; #ifdef GXV_LOAD_UNUSED_VARS FT_UShort order; #endif FT_UShort decomposedCount; FT_UInt i; GXV_LIMIT_CHECK( 4 + 4 + 2 + 2 ); lowerLimit = FT_NEXT_ULONG( p ); upperLimit = FT_NEXT_ULONG( p ); #ifdef GXV_LOAD_UNUSED_VARS order = FT_NEXT_USHORT( p ); #else p += 2; #endif decomposedCount = FT_NEXT_USHORT( p ); if ( lowerLimit >= upperLimit ) { GXV_TRACE(( "just table includes invalid range spec:" " lowerLimit(%d) > upperLimit(%d)\n" )); GXV_SET_ERR_IF_PARANOID( FT_INVALID_DATA ); } for ( i = 0; i < decomposedCount; i++ ) { FT_UShort glyphs; GXV_LIMIT_CHECK( 2 ); glyphs = FT_NEXT_USHORT( p ); gxv_just_check_max_gid( glyphs, "type0:glyphs", gxvalid ); } gxvalid->subtable_length = p - table; }
gxv_bsln_validate( FT_Bytes table, FT_Face face, FT_Validator ftvalid ) { GXV_ValidatorRec validrec; GXV_Validator valid = &validrec; GXV_bsln_DataRec bslnrec; GXV_bsln_Data bsln = &bslnrec; FT_Bytes p = table; FT_Bytes limit = 0; FT_ULong version; FT_UShort format; FT_UShort defaultBaseline; GXV_Validate_Func fmt_funcs_table [] = { gxv_bsln_parts_fmt0_validate, gxv_bsln_parts_fmt1_validate, gxv_bsln_parts_fmt2_validate, gxv_bsln_parts_fmt3_validate, }; valid->root = ftvalid; valid->table_data = bsln; valid->face = face; FT_TRACE3(( "validating `bsln' table\n" )); GXV_INIT; GXV_LIMIT_CHECK( 4 + 2 + 2 ); version = FT_NEXT_ULONG( p ); format = FT_NEXT_USHORT( p ); defaultBaseline = FT_NEXT_USHORT( p ); /* only version 1.0 is defined (1996) */ if ( version != 0x00010000UL ) FT_INVALID_FORMAT; /* only format 1, 2, 3 are defined (1996) */ GXV_TRACE(( " (format = %d)\n", format )); if ( format > 3 ) FT_INVALID_FORMAT; if ( defaultBaseline > 31 ) FT_INVALID_FORMAT; bsln->defaultBaseline = defaultBaseline; fmt_funcs_table[format]( p, limit, valid ); FT_TRACE4(( "\n" )); }
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" )); }
static void gxv_mort_subtable_type5_InsertList_validate( FT_UShort offset, FT_UShort count, FT_Bytes table, FT_Bytes limit, GXV_Validator gxvalid ) { /* * We don't know the range of insertion-glyph-list. * Set range by whole of state table. */ FT_Bytes p = table + offset; GXV_mort_subtable_type5_StateOptRecData optdata = (GXV_mort_subtable_type5_StateOptRecData)gxvalid->statetable.optdata; if ( optdata->classTable < offset && offset < optdata->classTable + *(optdata->classTable_length_p) ) GXV_TRACE(( " offset runs into ClassTable" )); if ( optdata->stateArray < offset && offset < optdata->stateArray + *(optdata->stateArray_length_p) ) GXV_TRACE(( " offset runs into StateArray" )); if ( optdata->entryTable < offset && offset < optdata->entryTable + *(optdata->entryTable_length_p) ) GXV_TRACE(( " offset runs into EntryTable" )); #ifndef GXV_LOAD_TRACE_VARS GXV_LIMIT_CHECK( count * 2 ); #else while ( p < table + offset + ( count * 2 ) ) { FT_UShort insert_glyphID; GXV_LIMIT_CHECK( 2 ); insert_glyphID = FT_NEXT_USHORT( p ); GXV_TRACE(( " 0x%04x", insert_glyphID )); } GXV_TRACE(( "\n" )); #endif }
static void gxv_kern_subtable_fmt1_valueTable_load( FT_Bytes table, FT_Bytes limit, GXV_Validator gxvalid ) { FT_Bytes p = table; GXV_kern_fmt1_StateOptRecData optdata = (GXV_kern_fmt1_StateOptRecData)gxvalid->statetable.optdata; GXV_LIMIT_CHECK( 2 ); optdata->valueTable = FT_NEXT_USHORT( p ); }
static void gxv_just_actSubrecord_type1_validate( FT_Bytes table, FT_Bytes limit, GXV_Validator valid ) { FT_Bytes p = table; FT_UShort addGlyph; GXV_LIMIT_CHECK( 2 ); addGlyph = FT_NEXT_USHORT( p ); valid->subtable_length = p - table; }
static void gxv_morx_subtable_type1_substitutionTable_load( FT_Bytes table, FT_Bytes limit, GXV_Validator valid ) { FT_Bytes p = table; GXV_morx_subtable_type1_StateOptRecData optdata = (GXV_morx_subtable_type1_StateOptRecData)valid->xstatetable.optdata; GXV_LIMIT_CHECK( 2 ); optdata->substitutionTable = FT_NEXT_USHORT( p ); }
static void gxv_trak_trackTable_validate( FT_Bytes table, FT_Bytes limit, FT_UShort nTracks, GXV_Validator gxvalid ) { FT_Bytes p = table; FT_Fixed track, t; FT_UShort nameIndex; FT_UShort offset; FT_UShort i, j; GXV_NAME_ENTER( "trackTable" ); GXV_TRAK_DATA( trackValueOffset_min ) = 0xFFFFU; GXV_TRAK_DATA( trackValueOffset_max ) = 0x0000; GXV_LIMIT_CHECK( nTracks * ( 4 + 2 + 2 ) ); for ( i = 0; i < nTracks; i ++ ) { p = table + i * ( 4 + 2 + 2 ); track = FT_NEXT_LONG( p ); nameIndex = FT_NEXT_USHORT( p ); offset = FT_NEXT_USHORT( p ); if ( offset < GXV_TRAK_DATA( trackValueOffset_min ) ) GXV_TRAK_DATA( trackValueOffset_min ) = offset; if ( offset > GXV_TRAK_DATA( trackValueOffset_max ) ) GXV_TRAK_DATA( trackValueOffset_max ) = offset; gxv_sfntName_validate( nameIndex, 256, 32767, gxvalid ); for ( j = i; j < nTracks; j ++ ) { p = table + j * ( 4 + 2 + 2 ); t = FT_NEXT_LONG( p ); if ( t == track ) GXV_TRACE(( "duplicated entries found for track value 0x%x\n", track )); } } gxvalid->subtable_length = p - table; GXV_EXIT; }
/* * passed table & limit are of whole StateTable, not including subtables */ static void gxv_kern_subtable_fmt1_entry_validate( FT_Byte state, FT_UShort flags, GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, FT_Bytes table, FT_Bytes limit, GXV_Validator gxvalid ) { #ifdef GXV_LOAD_UNUSED_VARS FT_UShort push; FT_UShort dontAdvance; #endif FT_UShort valueOffset; #ifdef GXV_LOAD_UNUSED_VARS FT_UShort kernAction; FT_UShort kernValue; #endif FT_UNUSED( state ); FT_UNUSED( glyphOffset_p ); #ifdef GXV_LOAD_UNUSED_VARS push = (FT_UShort)( ( flags >> 15 ) & 1 ); dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 ); #endif valueOffset = (FT_UShort)( flags & 0x3FFF ); { GXV_kern_fmt1_StateOptRecData vt_rec = (GXV_kern_fmt1_StateOptRecData)gxvalid->statetable.optdata; FT_Bytes p; if ( valueOffset < vt_rec->valueTable ) FT_INVALID_OFFSET; p = table + valueOffset; limit = table + vt_rec->valueTable + vt_rec->valueTable_length; GXV_LIMIT_CHECK( 2 + 2 ); #ifdef GXV_LOAD_UNUSED_VARS kernAction = FT_NEXT_USHORT( p ); kernValue = FT_NEXT_USHORT( p ); #endif } }
static void gxv_just_actSubrecord_type1_validate( FT_Bytes table, FT_Bytes limit, GXV_Validator gxvalid ) { FT_Bytes p = table; FT_UShort addGlyph; GXV_LIMIT_CHECK( 2 ); addGlyph = FT_NEXT_USHORT( p ); gxv_just_check_max_gid( addGlyph, "type1:addGlyph", gxvalid ); gxvalid->subtable_length = (FT_ULong)( p - table ); }