otv_u_x_y_Ox_sy( FT_Bytes table, OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt GlyphCount, Count, count1; OTV_ENTER; p += 2; /* skip Format */ OTV_LIMIT_CHECK( 4 ); GlyphCount = FT_NEXT_USHORT( p ); Count = FT_NEXT_USHORT( p ); OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); OTV_TRACE(( " (Count = %d)\n", Count )); OTV_LIMIT_CHECK( GlyphCount * 2 + Count * 4 ); for ( count1 = GlyphCount; count1 > 0; count1-- ) otv_Coverage_validate( table + FT_NEXT_USHORT( p ), otvalid, -1 ); for ( ; Count > 0; Count-- ) { if ( FT_NEXT_USHORT( p ) >= GlyphCount ) FT_INVALID_DATA; if ( FT_NEXT_USHORT( p ) >= otvalid->lookup_count ) FT_INVALID_DATA; } OTV_EXIT; }
otv_x_y_ux_sy( FT_Bytes table, OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt Count1, Count2; OTV_ENTER; OTV_LIMIT_CHECK( 4 ); Count1 = FT_NEXT_USHORT( p ); Count2 = FT_NEXT_USHORT( p ); OTV_TRACE(( " (Count1 = %d)\n", Count1 )); OTV_TRACE(( " (Count2 = %d)\n", Count2 )); if ( Count1 == 0 ) FT_INVALID_DATA; OTV_LIMIT_CHECK( ( Count1 - 1 ) * 2 + Count2 * 4 ); p += ( Count1 - 1 ) * 2; for ( ; Count2 > 0; Count2-- ) { if ( FT_NEXT_USHORT( p ) >= Count1 ) FT_INVALID_DATA; if ( FT_NEXT_USHORT( p ) >= otvalid->extra1 ) FT_INVALID_DATA; } OTV_EXIT; }
static void otv_BaseValues_validate( FT_Bytes table, OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt BaseCoordCount; OTV_NAME_ENTER( "BaseValues" ); OTV_LIMIT_CHECK( 4 ); p += 2; /* skip DefaultIndex */ BaseCoordCount = FT_NEXT_USHORT( p ); OTV_TRACE(( " (BaseCoordCount = %d)\n", BaseCoordCount )); OTV_LIMIT_CHECK( BaseCoordCount * 2 ); /* BaseCoord */ for ( ; BaseCoordCount > 0; BaseCoordCount-- ) otv_BaseCoord_validate( table + FT_NEXT_USHORT( p ), otvalid ); OTV_EXIT; }
otv_u_C_x_Ox( FT_Bytes table, OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt Count, Coverage; OTV_Validate_Func func; OTV_ENTER; p += 2; /* skip Format */ OTV_LIMIT_CHECK( 4 ); Coverage = FT_NEXT_USHORT( p ); Count = FT_NEXT_USHORT( p ); OTV_TRACE(( " (Count = %d)\n", Count )); otv_Coverage_validate( table + Coverage, otvalid, (FT_Int)Count ); OTV_LIMIT_CHECK( Count * 2 ); otvalid->nesting_level++; func = otvalid->func[otvalid->nesting_level]; for ( ; Count > 0; Count-- ) func( table + FT_NEXT_USHORT( p ), otvalid ); otvalid->nesting_level--; OTV_EXIT; }
otv_x_ux( FT_Bytes table, OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt Count; OTV_ENTER; OTV_LIMIT_CHECK( 2 ); Count = FT_NEXT_USHORT( p ); OTV_TRACE(( " (Count = %d)\n", Count )); OTV_LIMIT_CHECK( Count * 2 ); if ( otvalid->extra1 ) { for ( ; Count > 0; Count-- ) if ( FT_NEXT_USHORT( p ) >= otvalid->extra1 ) FT_INVALID_DATA; } OTV_EXIT; }
otv_ScriptList_validate( FT_Bytes table, FT_Bytes features, OTV_Validator otvalid ) { FT_UInt ScriptCount; FT_Bytes p = table; OTV_NAME_ENTER( "ScriptList" ); OTV_LIMIT_CHECK( 2 ); ScriptCount = FT_NEXT_USHORT( p ); OTV_TRACE(( " (ScriptCount = %d)\n", ScriptCount )); OTV_LIMIT_CHECK( ScriptCount * 6 ); otvalid->extra1 = otv_Feature_get_count( features ); /* ScriptRecord */ for ( ; ScriptCount > 0; ScriptCount-- ) { p += 4; /* skip ScriptTag */ otv_Script_validate( table + FT_NEXT_USHORT( p ), otvalid ); /* Script */ } OTV_EXIT; }
static void otv_Ligature_validate( FT_Bytes table, OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt LigatureGlyph, CompCount; OTV_ENTER; OTV_LIMIT_CHECK( 4 ); LigatureGlyph = FT_NEXT_USHORT( p ); if ( LigatureGlyph >= otvalid->glyph_count ) FT_INVALID_DATA; CompCount = FT_NEXT_USHORT( p ); OTV_TRACE(( " (CompCount = %d)\n", CompCount )); if ( CompCount == 0 ) FT_INVALID_DATA; CompCount--; OTV_LIMIT_CHECK( CompCount * 2 ); /* Component */ /* no need to check the Component glyph indices */ OTV_EXIT; }
otv_LangSys_validate( FT_Bytes table, OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt ReqFeatureIndex; FT_UInt FeatureCount; OTV_NAME_ENTER( "LangSys" ); OTV_LIMIT_CHECK( 6 ); p += 2; /* skip LookupOrder (unused) */ ReqFeatureIndex = FT_NEXT_USHORT( p ); FeatureCount = FT_NEXT_USHORT( p ); OTV_TRACE(( " (ReqFeatureIndex = %d)\n", ReqFeatureIndex )); OTV_TRACE(( " (FeatureCount = %d)\n", FeatureCount )); if ( ReqFeatureIndex != 0xFFFFU && ReqFeatureIndex >= otvalid->extra1 ) FT_INVALID_DATA; OTV_LIMIT_CHECK( FeatureCount * 2 ); /* FeatureIndex */ for ( ; FeatureCount > 0; FeatureCount-- ) if ( FT_NEXT_USHORT( p ) >= otvalid->extra1 ) FT_INVALID_DATA; OTV_EXIT; }
otv_Script_validate( FT_Bytes table, OTV_Validator otvalid ) { FT_UInt DefaultLangSys, LangSysCount; FT_Bytes p = table; OTV_NAME_ENTER( "Script" ); OTV_LIMIT_CHECK( 4 ); DefaultLangSys = FT_NEXT_USHORT( p ); LangSysCount = FT_NEXT_USHORT( p ); OTV_TRACE(( " (LangSysCount = %d)\n", LangSysCount )); if ( DefaultLangSys != 0 ) otv_LangSys_validate( table + DefaultLangSys, otvalid ); OTV_LIMIT_CHECK( LangSysCount * 6 ); /* LangSysRecord */ for ( ; LangSysCount > 0; LangSysCount-- ) { p += 4; /* skip LangSysTag */ /* LangSys */ otv_LangSys_validate( table + FT_NEXT_USHORT( p ), otvalid ); } OTV_EXIT; }
otv_FeatureList_validate( FT_Bytes table, FT_Bytes lookups, OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt FeatureCount; OTV_NAME_ENTER( "FeatureList" ); OTV_LIMIT_CHECK( 2 ); FeatureCount = FT_NEXT_USHORT( p ); OTV_TRACE(( " (FeatureCount = %d)\n", FeatureCount )); OTV_LIMIT_CHECK( FeatureCount * 2 ); otvalid->lookup_count = otv_LookupList_get_count( lookups ); /* FeatureRecord */ for ( ; FeatureCount > 0; FeatureCount-- ) { p += 4; /* skip FeatureTag */ /* Feature */ otv_Feature_validate( table + FT_NEXT_USHORT( p ), otvalid ); } OTV_EXIT; }
otv_Lookup_validate( FT_Bytes table, OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt LookupType, SubTableCount; OTV_Validate_Func validate; OTV_NAME_ENTER( "Lookup" ); OTV_LIMIT_CHECK( 6 ); LookupType = FT_NEXT_USHORT( p ); p += 2; /* skip LookupFlag */ SubTableCount = FT_NEXT_USHORT( p ); OTV_TRACE(( " (type %d)\n", LookupType )); if ( LookupType == 0 || LookupType > otvalid->type_count ) FT_INVALID_DATA; validate = otvalid->type_funcs[LookupType - 1]; OTV_TRACE(( " (SubTableCount = %d)\n", SubTableCount )); OTV_LIMIT_CHECK( SubTableCount * 2 ); /* SubTable */ for ( ; SubTableCount > 0; SubTableCount-- ) validate( table + FT_NEXT_USHORT( p ), otvalid ); OTV_EXIT; }
otv_Device_validate( FT_Bytes table, OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt StartSize, EndSize, DeltaFormat, count; OTV_NAME_ENTER( "Device" ); OTV_LIMIT_CHECK( 8 ); StartSize = FT_NEXT_USHORT( p ); EndSize = FT_NEXT_USHORT( p ); DeltaFormat = FT_NEXT_USHORT( p ); if ( DeltaFormat < 1 || DeltaFormat > 3 ) FT_INVALID_FORMAT; if ( EndSize < StartSize ) FT_INVALID_DATA; count = EndSize - StartSize + 1; OTV_LIMIT_CHECK( ( 1 << DeltaFormat ) * count / 8 ); /* DeltaValue */ OTV_EXIT; }
static void otv_BaseScriptList_validate( FT_Bytes table, OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt BaseScriptCount; OTV_NAME_ENTER( "BaseScriptList" ); OTV_LIMIT_CHECK( 2 ); BaseScriptCount = FT_NEXT_USHORT( p ); OTV_TRACE(( " (BaseScriptCount = %d)\n", BaseScriptCount )); OTV_LIMIT_CHECK( BaseScriptCount * 6 ); /* BaseScriptRecord */ for ( ; BaseScriptCount > 0; BaseScriptCount-- ) { p += 4; /* skip BaseScriptTag */ /* BaseScript */ otv_BaseScript_validate( table + FT_NEXT_USHORT( p ), otvalid ); } OTV_EXIT; }
otv_x_Ox( FT_Bytes table, OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt Count; OTV_Validate_Func func; OTV_ENTER; OTV_LIMIT_CHECK( 2 ); Count = FT_NEXT_USHORT( p ); OTV_TRACE(( " (Count = %d)\n", Count )); OTV_LIMIT_CHECK( Count * 2 ); otvalid->nesting_level++; func = otvalid->func[otvalid->nesting_level]; for ( ; Count > 0; Count-- ) func( table + FT_NEXT_USHORT( p ), otvalid ); otvalid->nesting_level--; OTV_EXIT; }
static void otv_O_x_Ox( FT_Bytes table, OTV_Validator valid ) { FT_Bytes p = table; FT_Bytes Coverage; FT_UInt GlyphCount; OTV_Validate_Func func; OTV_ENTER; OTV_LIMIT_CHECK( 4 ); Coverage = table + FT_NEXT_USHORT( p ); GlyphCount = FT_NEXT_USHORT( p ); OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); otv_Coverage_validate( Coverage, valid, GlyphCount ); if ( GlyphCount != otv_Coverage_get_count( Coverage ) ) FT_INVALID_DATA; OTV_LIMIT_CHECK( GlyphCount * 2 ); valid->nesting_level++; func = valid->func[valid->nesting_level]; valid->extra1 = 0; for ( ; GlyphCount > 0; GlyphCount-- ) func( table + FT_NEXT_USHORT( p ), valid ); valid->nesting_level--; OTV_EXIT; }
otv_u_x_Ox_y_Oy_z_Oz_p_sp( FT_Bytes table, OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt BacktrackGlyphCount, InputGlyphCount, LookaheadGlyphCount; FT_UInt count1, count2; OTV_ENTER; p += 2; /* skip Format */ OTV_LIMIT_CHECK( 2 ); BacktrackGlyphCount = FT_NEXT_USHORT( p ); OTV_TRACE(( " (BacktrackGlyphCount = %d)\n", BacktrackGlyphCount )); OTV_LIMIT_CHECK( BacktrackGlyphCount * 2 + 2 ); for ( ; BacktrackGlyphCount > 0; BacktrackGlyphCount-- ) otv_Coverage_validate( table + FT_NEXT_USHORT( p ), otvalid, -1 ); InputGlyphCount = FT_NEXT_USHORT( p ); OTV_TRACE(( " (InputGlyphCount = %d)\n", InputGlyphCount )); OTV_LIMIT_CHECK( InputGlyphCount * 2 + 2 ); for ( count1 = InputGlyphCount; count1 > 0; count1-- ) otv_Coverage_validate( table + FT_NEXT_USHORT( p ), otvalid, -1 ); LookaheadGlyphCount = FT_NEXT_USHORT( p ); OTV_TRACE(( " (LookaheadGlyphCount = %d)\n", LookaheadGlyphCount )); OTV_LIMIT_CHECK( LookaheadGlyphCount * 2 + 2 ); for ( ; LookaheadGlyphCount > 0; LookaheadGlyphCount-- ) otv_Coverage_validate( table + FT_NEXT_USHORT( p ), otvalid, -1 ); count2 = FT_NEXT_USHORT( p ); OTV_TRACE(( " (Count = %d)\n", count2 )); OTV_LIMIT_CHECK( count2 * 4 ); for ( ; count2 > 0; count2-- ) { if ( FT_NEXT_USHORT( p ) >= InputGlyphCount ) FT_INVALID_DATA; if ( FT_NEXT_USHORT( p ) >= otvalid->lookup_count ) FT_INVALID_DATA; } OTV_EXIT; }
static void otv_MinMax_validate( FT_Bytes table, OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt table_size; FT_UInt FeatMinMaxCount; OTV_OPTIONAL_TABLE( MinCoord ); OTV_OPTIONAL_TABLE( MaxCoord ); OTV_NAME_ENTER( "MinMax" ); OTV_LIMIT_CHECK( 6 ); OTV_OPTIONAL_OFFSET( MinCoord ); OTV_OPTIONAL_OFFSET( MaxCoord ); FeatMinMaxCount = FT_NEXT_USHORT( p ); OTV_TRACE(( " (FeatMinMaxCount = %d)\n", FeatMinMaxCount )); table_size = FeatMinMaxCount * 8 + 6; OTV_SIZE_CHECK( MinCoord ); if ( MinCoord ) otv_BaseCoord_validate( table + MinCoord, otvalid ); OTV_SIZE_CHECK( MaxCoord ); if ( MaxCoord ) otv_BaseCoord_validate( table + MaxCoord, otvalid ); OTV_LIMIT_CHECK( FeatMinMaxCount * 8 ); /* FeatMinMaxRecord */ for ( ; FeatMinMaxCount > 0; FeatMinMaxCount-- ) { p += 4; /* skip FeatureTableTag */ OTV_OPTIONAL_OFFSET( MinCoord ); OTV_OPTIONAL_OFFSET( MaxCoord ); OTV_SIZE_CHECK( MinCoord ); if ( MinCoord ) otv_BaseCoord_validate( table + MinCoord, otvalid ); OTV_SIZE_CHECK( MaxCoord ); if ( MaxCoord ) otv_BaseCoord_validate( table + MaxCoord, otvalid ); } OTV_EXIT; }
otv_JSTF_validate( FT_Bytes table, FT_Bytes gsub, FT_Bytes gpos, FT_UInt glyph_count, FT_Validator ftvalid ) { OTV_ValidatorRec otvalidrec; OTV_Validator otvalid = &otvalidrec; FT_Bytes p = table; FT_UInt JstfScriptCount; otvalid->root = ftvalid; FT_TRACE3(( "validating JSTF table\n" )); OTV_INIT; OTV_LIMIT_CHECK( 6 ); if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ FT_INVALID_FORMAT; JstfScriptCount = FT_NEXT_USHORT( p ); FT_TRACE3(( " (JstfScriptCount = %d)\n", JstfScriptCount )); OTV_LIMIT_CHECK( JstfScriptCount * 6 ); if ( gsub ) otvalid->extra1 = otv_GSUBGPOS_get_Lookup_count( gsub ); else otvalid->extra1 = 0; if ( gpos ) otvalid->extra2 = otv_GSUBGPOS_get_Lookup_count( gpos ); else otvalid->extra2 = 0; otvalid->glyph_count = glyph_count; /* JstfScriptRecord */ for ( ; JstfScriptCount > 0; JstfScriptCount-- ) { p += 4; /* skip JstfScriptTag */ /* JstfScript */ otv_JstfScript_validate( table + FT_NEXT_USHORT( p ), otvalid ); } FT_TRACE4(( "\n" )); }
otv_x_ux_y_uy_z_uz_p_sp( FT_Bytes table, OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt BacktrackCount, InputCount, LookaheadCount; FT_UInt Count; OTV_ENTER; OTV_LIMIT_CHECK( 2 ); BacktrackCount = FT_NEXT_USHORT( p ); OTV_TRACE(( " (BacktrackCount = %d)\n", BacktrackCount )); OTV_LIMIT_CHECK( BacktrackCount * 2 + 2 ); p += BacktrackCount * 2; InputCount = FT_NEXT_USHORT( p ); if ( InputCount == 0 ) FT_INVALID_DATA; OTV_TRACE(( " (InputCount = %d)\n", InputCount )); OTV_LIMIT_CHECK( InputCount * 2 ); p += ( InputCount - 1 ) * 2; LookaheadCount = FT_NEXT_USHORT( p ); OTV_TRACE(( " (LookaheadCount = %d)\n", LookaheadCount )); OTV_LIMIT_CHECK( LookaheadCount * 2 + 2 ); p += LookaheadCount * 2; Count = FT_NEXT_USHORT( p ); OTV_TRACE(( " (Count = %d)\n", Count )); OTV_LIMIT_CHECK( Count * 4 ); for ( ; Count > 0; Count-- ) { if ( FT_NEXT_USHORT( p ) >= InputCount ) FT_INVALID_DATA; if ( FT_NEXT_USHORT( p ) >= otvalid->extra1 ) FT_INVALID_DATA; } OTV_EXIT; }
static void otv_JstfScript_validate( FT_Bytes table, OTV_Validator valid ) { FT_Bytes p = table; FT_UInt table_size; FT_UInt JstfLangSysCount; OTV_OPTIONAL_TABLE( ExtGlyph ); OTV_OPTIONAL_TABLE( DefJstfLangSys ); OTV_NAME_ENTER( "JstfScript" ); OTV_LIMIT_CHECK( 6 ); OTV_OPTIONAL_OFFSET( ExtGlyph ); OTV_OPTIONAL_OFFSET( DefJstfLangSys ); JstfLangSysCount = FT_NEXT_USHORT( p ); OTV_TRACE(( " (JstfLangSysCount = %d)\n", JstfLangSysCount )); table_size = JstfLangSysCount * 6 + 6; OTV_SIZE_CHECK( ExtGlyph ); if ( ExtGlyph ) { valid->extra1 = valid->glyph_count; OTV_NEST1( ExtenderGlyph ); OTV_RUN( table + ExtGlyph, valid ); } OTV_SIZE_CHECK( DefJstfLangSys ); if ( DefJstfLangSys ) { OTV_NEST2( JstfLangSys, JstfPriority ); OTV_RUN( table + DefJstfLangSys, valid ); } OTV_LIMIT_CHECK( 6 * JstfLangSysCount ); /* JstfLangSysRecord */ OTV_NEST2( JstfLangSys, JstfPriority ); for ( ; JstfLangSysCount > 0; JstfLangSysCount-- ) { p += 4; /* skip JstfLangSysTag */ OTV_RUN( table + FT_NEXT_USHORT( p ), valid ); } OTV_EXIT; }
static void otv_MathVariants_validate( FT_Bytes table, OTV_Validator valid ) { FT_Bytes p = table; FT_UInt vcnt, hcnt, i, table_size; OTV_OPTIONAL_TABLE( VCoverage ); OTV_OPTIONAL_TABLE( HCoverage ); OTV_OPTIONAL_TABLE( Offset ); OTV_NAME_ENTER( "MathVariants" ); OTV_LIMIT_CHECK( 10 ); p += 2; /* Skip the MinConnectorOverlap constant */ OTV_OPTIONAL_OFFSET( VCoverage ); OTV_OPTIONAL_OFFSET( HCoverage ); vcnt = FT_NEXT_USHORT( p ); hcnt = FT_NEXT_USHORT( p ); OTV_LIMIT_CHECK( 2 * vcnt + 2 * hcnt ); table_size = 10 + 2 * vcnt + 2 * hcnt; OTV_SIZE_CHECK( VCoverage ); if ( VCoverage ) otv_Coverage_validate( table + VCoverage, valid, vcnt ); OTV_SIZE_CHECK( HCoverage ); if ( HCoverage ) otv_Coverage_validate( table + HCoverage, valid, hcnt ); for ( i = 0; i < vcnt; ++i ) { OTV_OPTIONAL_OFFSET( Offset ); OTV_SIZE_CHECK( Offset ); otv_MathGlyphConstruction_validate( table + Offset, valid ); } for ( i = 0; i < hcnt; ++i ) { OTV_OPTIONAL_OFFSET( Offset ); OTV_SIZE_CHECK( Offset ); otv_MathGlyphConstruction_validate( table + Offset, valid ); } OTV_EXIT; }
otv_u_O_O_O_O_x_Onx( FT_Bytes table, OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt Coverage; FT_UInt BacktrackClassDef, InputClassDef, LookaheadClassDef; FT_UInt ChainClassSetCount; OTV_Validate_Func func; OTV_ENTER; p += 2; /* skip Format */ OTV_LIMIT_CHECK( 10 ); Coverage = FT_NEXT_USHORT( p ); BacktrackClassDef = FT_NEXT_USHORT( p ); InputClassDef = FT_NEXT_USHORT( p ); LookaheadClassDef = FT_NEXT_USHORT( p ); ChainClassSetCount = FT_NEXT_USHORT( p ); OTV_TRACE(( " (ChainClassSetCount = %d)\n", ChainClassSetCount )); otv_Coverage_validate( table + Coverage, otvalid, -1 ); otv_ClassDef_validate( table + BacktrackClassDef, otvalid ); otv_ClassDef_validate( table + InputClassDef, otvalid ); otv_ClassDef_validate( table + LookaheadClassDef, otvalid ); OTV_LIMIT_CHECK( ChainClassSetCount * 2 ); otvalid->nesting_level++; func = otvalid->func[otvalid->nesting_level]; otvalid->extra1 = otvalid->lookup_count; for ( ; ChainClassSetCount > 0; ChainClassSetCount-- ) { FT_UInt offset = FT_NEXT_USHORT( p ); if ( offset ) func( table + offset, otvalid ); } otvalid->nesting_level--; OTV_EXIT; }
static void otv_MathConstants_validate( FT_Bytes table, OTV_Validator valid ) { FT_Bytes p = table; FT_UInt i; FT_UInt table_size; OTV_OPTIONAL_TABLE( DeviceTableOffset ); OTV_NAME_ENTER( "MathConstants" ); /* 56 constants, 51 have device tables */ OTV_LIMIT_CHECK( 2 * ( 56 + 51 ) ); table_size = 2 * ( 56 + 51 ); p += 4 * 2; /* First 4 constants have no device tables */ for ( i = 0; i < 51; ++i ) { p += 2; /* skip the value */ OTV_OPTIONAL_OFFSET( DeviceTableOffset ); OTV_SIZE_CHECK( DeviceTableOffset ); if ( DeviceTableOffset ) otv_Device_validate( table + DeviceTableOffset, valid ); } OTV_EXIT; }
otv_MATH_validate( FT_Bytes table, FT_UInt glyph_count, FT_Validator ftvalid ) { OTV_ValidatorRec validrec; OTV_Validator valid = &validrec; FT_Bytes p = table; FT_UInt MathConstants, MathGlyphInfo, MathVariants; valid->root = ftvalid; FT_TRACE3(( "validating MATH table\n" )); OTV_INIT; OTV_LIMIT_CHECK( 10 ); if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ FT_INVALID_FORMAT; MathConstants = FT_NEXT_USHORT( p ); MathGlyphInfo = FT_NEXT_USHORT( p ); MathVariants = FT_NEXT_USHORT( p ); valid->glyph_count = glyph_count; otv_MathConstants_validate( table + MathConstants, valid ); otv_MathGlyphInfo_validate( table + MathGlyphInfo, valid ); otv_MathVariants_validate ( table + MathVariants, valid ); FT_TRACE4(( "\n" )); }
static void otv_Axis_validate( FT_Bytes table, OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt table_size; OTV_OPTIONAL_TABLE( BaseTagList ); OTV_NAME_ENTER( "Axis" ); OTV_LIMIT_CHECK( 4 ); OTV_OPTIONAL_OFFSET( BaseTagList ); table_size = 4; OTV_SIZE_CHECK( BaseTagList ); if ( BaseTagList ) otv_BaseTagList_validate( table + BaseTagList, otvalid ); /* BaseScriptList */ otv_BaseScriptList_validate( table + FT_NEXT_USHORT( p ), otvalid ); OTV_EXIT; }
static void otv_MultipleSubst_validate( FT_Bytes table, OTV_Validator valid ) { FT_Bytes p = table; FT_UInt SubstFormat; OTV_NAME_ENTER( "MultipleSubst" ); OTV_LIMIT_CHECK( 2 ); SubstFormat = FT_NEXT_USHORT( p ); OTV_TRACE(( " (format %d)\n", SubstFormat )); switch ( SubstFormat ) { case 1: valid->extra1 = valid->glyph_count; OTV_NEST2( MultipleSubstFormat1, Sequence ); OTV_RUN( table, valid ); break; default: FT_INVALID_DATA; } OTV_EXIT; }
static void otv_LigatureSubst_validate( FT_Bytes table, OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt SubstFormat; OTV_NAME_ENTER( "LigatureSubst" ); OTV_LIMIT_CHECK( 2 ); SubstFormat = FT_NEXT_USHORT( p ); OTV_TRACE(( " (format %d)\n", SubstFormat )); switch ( SubstFormat ) { case 1: OTV_NEST3( LigatureSubstFormat1, LigatureSet, Ligature ); OTV_RUN( table, otvalid ); break; default: FT_INVALID_FORMAT; } OTV_EXIT; }
static void otv_AlternateSubst_validate( FT_Bytes table, OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt SubstFormat; OTV_NAME_ENTER( "AlternateSubst" ); OTV_LIMIT_CHECK( 2 ); SubstFormat = FT_NEXT_USHORT( p ); OTV_TRACE(( " (format %d)\n", SubstFormat )); switch ( SubstFormat ) { case 1: otvalid->extra1 = otvalid->glyph_count; OTV_NEST2( AlternateSubstFormat1, AlternateSet ); OTV_RUN( table, otvalid ); break; default: FT_INVALID_FORMAT; } OTV_EXIT; }
static void otv_ExtensionSubst_validate( FT_Bytes table, OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt SubstFormat; OTV_NAME_ENTER( "ExtensionSubst" ); OTV_LIMIT_CHECK( 2 ); SubstFormat = FT_NEXT_USHORT( p ); OTV_TRACE(( " (format %d)\n", SubstFormat )); switch ( SubstFormat ) { case 1: /* ExtensionSubstFormat1 */ { FT_UInt ExtensionLookupType; FT_ULong ExtensionOffset; OTV_Validate_Func validate; OTV_LIMIT_CHECK( 6 ); ExtensionLookupType = FT_NEXT_USHORT( p ); ExtensionOffset = FT_NEXT_ULONG( p ); if ( ExtensionLookupType == 0 || ExtensionLookupType == 7 || ExtensionLookupType > 8 ) FT_INVALID_DATA; validate = otvalid->type_funcs[ExtensionLookupType - 1]; validate( table + ExtensionOffset, otvalid ); } break; default: FT_INVALID_FORMAT; } OTV_EXIT; }
static void otv_BaseScript_validate( FT_Bytes table, OTV_Validator otvalid ) { FT_Bytes p = table; FT_UInt table_size; FT_UInt BaseLangSysCount; OTV_OPTIONAL_TABLE( BaseValues ); OTV_OPTIONAL_TABLE( DefaultMinMax ); OTV_NAME_ENTER( "BaseScript" ); OTV_LIMIT_CHECK( 6 ); OTV_OPTIONAL_OFFSET( BaseValues ); OTV_OPTIONAL_OFFSET( DefaultMinMax ); BaseLangSysCount = FT_NEXT_USHORT( p ); OTV_TRACE(( " (BaseLangSysCount = %d)\n", BaseLangSysCount )); table_size = BaseLangSysCount * 6 + 6; OTV_SIZE_CHECK( BaseValues ); if ( BaseValues ) otv_BaseValues_validate( table + BaseValues, otvalid ); OTV_SIZE_CHECK( DefaultMinMax ); if ( DefaultMinMax ) otv_MinMax_validate( table + DefaultMinMax, otvalid ); OTV_LIMIT_CHECK( BaseLangSysCount * 6 ); /* BaseLangSysRecord */ for ( ; BaseLangSysCount > 0; BaseLangSysCount-- ) { p += 4; /* skip BaseLangSysTag */ otv_MinMax_validate( table + FT_NEXT_USHORT( p ), otvalid ); } OTV_EXIT; }