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; }
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; }
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; }
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_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; }
static void otv_MathItalicsCorrectionInfo_validate( FT_Bytes table, OTV_Validator otvalid, FT_Int isItalic ) { FT_Bytes p = table; FT_UInt i, cnt, table_size; OTV_OPTIONAL_TABLE( Coverage ); OTV_OPTIONAL_TABLE( DeviceTableOffset ); FT_UNUSED( isItalic ); /* only used if tracing is active */ OTV_NAME_ENTER( isItalic ? "MathItalicsCorrectionInfo" : "MathTopAccentAttachment" ); OTV_LIMIT_CHECK( 4 ); OTV_OPTIONAL_OFFSET( Coverage ); cnt = FT_NEXT_USHORT( p ); OTV_LIMIT_CHECK( 4 * cnt ); table_size = 4 + 4 * cnt; OTV_SIZE_CHECK( Coverage ); otv_Coverage_validate( table + Coverage, otvalid, (FT_Int)cnt ); for ( i = 0; i < cnt; ++i ) { p += 2; /* Skip the value */ OTV_OPTIONAL_OFFSET( DeviceTableOffset ); OTV_SIZE_CHECK( DeviceTableOffset ); if ( DeviceTableOffset ) otv_Device_validate( table + DeviceTableOffset, otvalid ); } OTV_EXIT; }
static void otv_MathKernInfo_validate( FT_Bytes table, OTV_Validator valid ) { FT_Bytes p = table; FT_UInt i, j, cnt, table_size; OTV_OPTIONAL_TABLE( Coverage ); OTV_OPTIONAL_TABLE( MKRecordOffset ); OTV_NAME_ENTER( "MathKernInfo" ); OTV_LIMIT_CHECK( 4 ); OTV_OPTIONAL_OFFSET( Coverage ); cnt = FT_NEXT_USHORT( p ); OTV_LIMIT_CHECK( 8 * cnt ); table_size = 4 + 8 * cnt; OTV_SIZE_CHECK( Coverage ); otv_Coverage_validate( table + Coverage, valid, cnt ); for ( i = 0; i < cnt; ++i ) { for ( j = 0; j < 4; ++j ) { OTV_OPTIONAL_OFFSET( MKRecordOffset ); OTV_SIZE_CHECK( MKRecordOffset ); if ( MKRecordOffset ) otv_MathKern_validate( table + MKRecordOffset, valid ); } } OTV_EXIT; }
otv_BASE_validate( FT_Bytes table, FT_Validator ftvalid ) { OTV_ValidatorRec otvalidrec; OTV_Validator otvalid = &otvalidrec; FT_Bytes p = table; FT_UInt table_size; OTV_OPTIONAL_TABLE( HorizAxis ); OTV_OPTIONAL_TABLE( VertAxis ); otvalid->root = ftvalid; FT_TRACE3(( "validating BASE table\n" )); OTV_INIT; OTV_LIMIT_CHECK( 6 ); if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ FT_INVALID_FORMAT; table_size = 6; OTV_OPTIONAL_OFFSET( HorizAxis ); OTV_SIZE_CHECK( HorizAxis ); if ( HorizAxis ) otv_Axis_validate( table + HorizAxis, otvalid ); OTV_OPTIONAL_OFFSET( VertAxis ); OTV_SIZE_CHECK( VertAxis ); if ( VertAxis ) otv_Axis_validate( table + VertAxis, otvalid ); FT_TRACE4(( "\n" )); }
static void otv_MathKern_validate( FT_Bytes table, OTV_Validator valid ) { FT_Bytes p = table; FT_UInt i, cnt, table_size; OTV_OPTIONAL_TABLE( DeviceTableOffset ); /* OTV_NAME_ENTER( "MathKern" );*/ OTV_LIMIT_CHECK( 2 ); cnt = FT_NEXT_USHORT( p ); OTV_LIMIT_CHECK( 4 * cnt + 2 ); table_size = 4 + 4 * cnt; /* Heights */ for ( i = 0; i < cnt; ++i ) { p += 2; /* Skip the value */ OTV_OPTIONAL_OFFSET( DeviceTableOffset ); OTV_SIZE_CHECK( DeviceTableOffset ); if ( DeviceTableOffset ) otv_Device_validate( table + DeviceTableOffset, valid ); } /* One more Kerning value */ for ( i = 0; i < cnt + 1; ++i ) { p += 2; /* Skip the value */ OTV_OPTIONAL_OFFSET( DeviceTableOffset ); OTV_SIZE_CHECK( DeviceTableOffset ); if ( DeviceTableOffset ) otv_Device_validate( table + DeviceTableOffset, valid ); } OTV_EXIT; }
static void otv_GlyphAssembly_validate( FT_Bytes table, OTV_Validator valid ) { FT_Bytes p = table; FT_UInt pcnt, table_size; FT_UInt i; OTV_OPTIONAL_TABLE( DeviceTableOffset ); /* OTV_NAME_ENTER( "GlyphAssembly" ); */ OTV_LIMIT_CHECK( 6 ); p += 2; /* Skip the Italics Correction value */ OTV_OPTIONAL_OFFSET( DeviceTableOffset ); pcnt = FT_NEXT_USHORT( p ); OTV_LIMIT_CHECK( 8 * pcnt ); table_size = 6 + 8 * pcnt; OTV_SIZE_CHECK( DeviceTableOffset ); if ( DeviceTableOffset ) otv_Device_validate( table + DeviceTableOffset, valid ); for ( i = 0; i < pcnt; ++i ) { FT_UInt gid; gid = FT_NEXT_USHORT( p ); if ( gid >= valid->glyph_count ) FT_INVALID_GLYPH_ID; p += 2*4; /* skip the Start, End, Full, and Flags fields */ } /* OTV_EXIT; */ }
static void otv_MathGlyphConstruction_validate( FT_Bytes table, OTV_Validator valid ) { FT_Bytes p = table; FT_UInt vcnt, table_size; FT_UInt i; OTV_OPTIONAL_TABLE( GlyphAssembly ); /* OTV_NAME_ENTER( "MathGlyphConstruction" ); */ OTV_LIMIT_CHECK( 4 ); OTV_OPTIONAL_OFFSET( GlyphAssembly ); vcnt = FT_NEXT_USHORT( p ); OTV_LIMIT_CHECK( 4 * vcnt ); table_size = 4 + 4 * vcnt; for ( i = 0; i < vcnt; ++i ) { FT_UInt gid; gid = FT_NEXT_USHORT( p ); if ( gid >= valid->glyph_count ) FT_INVALID_GLYPH_ID; p += 2; /* skip the size */ } OTV_SIZE_CHECK( GlyphAssembly ); if ( GlyphAssembly ) otv_GlyphAssembly_validate( table+GlyphAssembly, valid ); /* OTV_EXIT; */ }
static void otv_JstfPriority_validate( FT_Bytes table, OTV_Validator valid ) { FT_Bytes p = table; FT_UInt table_size; FT_UInt gsub_lookup_count, gpos_lookup_count; OTV_OPTIONAL_TABLE( ShrinkageEnableGSUB ); OTV_OPTIONAL_TABLE( ShrinkageDisableGSUB ); OTV_OPTIONAL_TABLE( ShrinkageEnableGPOS ); OTV_OPTIONAL_TABLE( ShrinkageDisableGPOS ); OTV_OPTIONAL_TABLE( ExtensionEnableGSUB ); OTV_OPTIONAL_TABLE( ExtensionDisableGSUB ); OTV_OPTIONAL_TABLE( ExtensionEnableGPOS ); OTV_OPTIONAL_TABLE( ExtensionDisableGPOS ); OTV_OPTIONAL_TABLE( ShrinkageJstfMax ); OTV_OPTIONAL_TABLE( ExtensionJstfMax ); OTV_ENTER; OTV_TRACE(( "JstfPriority table\n" )); OTV_LIMIT_CHECK( 20 ); gsub_lookup_count = valid->extra1; gpos_lookup_count = valid->extra2; table_size = 20; valid->extra1 = gsub_lookup_count; OTV_OPTIONAL_OFFSET( ShrinkageEnableGSUB ); OTV_SIZE_CHECK( ShrinkageEnableGSUB ); if ( ShrinkageEnableGSUB ) otv_x_ux( table + ShrinkageEnableGSUB, valid ); OTV_OPTIONAL_OFFSET( ShrinkageDisableGSUB ); OTV_SIZE_CHECK( ShrinkageDisableGSUB ); if ( ShrinkageDisableGSUB ) otv_x_ux( table + ShrinkageDisableGSUB, valid ); valid->extra1 = gpos_lookup_count; OTV_OPTIONAL_OFFSET( ShrinkageEnableGPOS ); OTV_SIZE_CHECK( ShrinkageEnableGPOS ); if ( ShrinkageEnableGPOS ) otv_x_ux( table + ShrinkageEnableGPOS, valid ); OTV_OPTIONAL_OFFSET( ShrinkageDisableGPOS ); OTV_SIZE_CHECK( ShrinkageDisableGPOS ); if ( ShrinkageDisableGPOS ) otv_x_ux( table + ShrinkageDisableGPOS, valid ); OTV_OPTIONAL_OFFSET( ShrinkageJstfMax ); OTV_SIZE_CHECK( ShrinkageJstfMax ); if ( ShrinkageJstfMax ) { /* XXX: check lookup types? */ OTV_NEST2( JstfMax, JstfLookup ); OTV_RUN( table + ShrinkageJstfMax, valid ); } valid->extra1 = gsub_lookup_count; OTV_OPTIONAL_OFFSET( ExtensionEnableGSUB ); OTV_SIZE_CHECK( ExtensionEnableGSUB ); if ( ExtensionEnableGSUB ) otv_x_ux( table + ExtensionEnableGSUB, valid ); OTV_OPTIONAL_OFFSET( ExtensionDisableGSUB ); OTV_SIZE_CHECK( ExtensionDisableGSUB ); if ( ExtensionDisableGSUB ) otv_x_ux( table + ExtensionDisableGSUB, valid ); valid->extra1 = gpos_lookup_count; OTV_OPTIONAL_OFFSET( ExtensionEnableGPOS ); OTV_SIZE_CHECK( ExtensionEnableGPOS ); if ( ExtensionEnableGPOS ) otv_x_ux( table + ExtensionEnableGPOS, valid ); OTV_OPTIONAL_OFFSET( ExtensionDisableGPOS ); OTV_SIZE_CHECK( ExtensionDisableGPOS ); if ( ExtensionDisableGPOS ) otv_x_ux( table + ExtensionDisableGPOS, valid ); OTV_OPTIONAL_OFFSET( ExtensionJstfMax ); OTV_SIZE_CHECK( ExtensionJstfMax ); if ( ExtensionJstfMax ) { /* XXX: check lookup types? */ OTV_NEST2( JstfMax, JstfLookup ); OTV_RUN( table + ExtensionJstfMax, valid ); } valid->extra1 = gsub_lookup_count; valid->extra2 = gpos_lookup_count; OTV_EXIT; }
otv_GDEF_validate( FT_Bytes table, FT_Bytes gsub, FT_Bytes gpos, FT_Validator ftvalid ) { OTV_ValidatorRec validrec; OTV_Validator valid = &validrec; FT_Bytes p = table; FT_UInt table_size; FT_Bool need_MarkAttachClassDef; OTV_OPTIONAL_TABLE( GlyphClassDef ); OTV_OPTIONAL_TABLE( AttachListOffset ); OTV_OPTIONAL_TABLE( LigCaretListOffset ); OTV_OPTIONAL_TABLE( MarkAttachClassDef ); valid->root = ftvalid; FT_TRACE3(( "validating GDEF table\n" )); OTV_INIT; OTV_LIMIT_CHECK( 12 ); if ( FT_NEXT_ULONG( p ) != 0x10000UL ) /* Version */ FT_INVALID_FORMAT; /* MarkAttachClassDef has been added to the OpenType */ /* specification without increasing GDEF's version, */ /* so we use this ugly hack to find out whether the */ /* table is needed actually. */ need_MarkAttachClassDef = FT_BOOL( otv_GSUBGPOS_have_MarkAttachmentType_flag( gsub ) || otv_GSUBGPOS_have_MarkAttachmentType_flag( gpos ) ); if ( need_MarkAttachClassDef ) table_size = 12; /* OpenType >= 1.2 */ else table_size = 10; /* OpenType < 1.2 */ OTV_OPTIONAL_OFFSET( GlyphClassDef ); OTV_SIZE_CHECK( GlyphClassDef ); if ( GlyphClassDef ) otv_ClassDef_validate( table + GlyphClassDef, valid ); OTV_OPTIONAL_OFFSET( AttachListOffset ); OTV_SIZE_CHECK( AttachListOffset ); if ( AttachListOffset ) { OTV_NEST2( AttachList, AttachPoint ); OTV_RUN( table + AttachListOffset, valid ); } OTV_OPTIONAL_OFFSET( LigCaretListOffset ); OTV_SIZE_CHECK( LigCaretListOffset ); if ( LigCaretListOffset ) { OTV_NEST3( LigCaretList, LigGlyph, CaretValue ); OTV_RUN( table + LigCaretListOffset, valid ); } if ( need_MarkAttachClassDef ) { OTV_OPTIONAL_OFFSET( MarkAttachClassDef ); OTV_SIZE_CHECK( MarkAttachClassDef ); if ( MarkAttachClassDef ) otv_ClassDef_validate( table + MarkAttachClassDef, valid ); } FT_TRACE4(( "\n" )); }
otv_GDEF_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 table_size; FT_UShort version; FT_Bool need_MarkAttachClassDef = 1; OTV_OPTIONAL_TABLE( GlyphClassDef ); OTV_OPTIONAL_TABLE( AttachListOffset ); OTV_OPTIONAL_TABLE( LigCaretListOffset ); OTV_OPTIONAL_TABLE( MarkAttachClassDef ); OTV_OPTIONAL_TABLE( MarkGlyphSetsDef ); OTV_OPTIONAL_TABLE32( itemVarStore ); otvalid->root = ftvalid; FT_TRACE3(( "validating GDEF table\n" )); OTV_INIT; OTV_LIMIT_CHECK( 4 ); if ( FT_NEXT_USHORT( p ) != 1 ) /* majorVersion */ FT_INVALID_FORMAT; version = FT_NEXT_USHORT( p ); /* minorVersion */ table_size = 10; switch ( version ) { case 0: /* MarkAttachClassDef has been added to the OpenType */ /* specification without increasing GDEF's version, */ /* so we use this ugly hack to find out whether the */ /* table is needed actually. */ need_MarkAttachClassDef = FT_BOOL( otv_GSUBGPOS_have_MarkAttachmentType_flag( gsub ) || otv_GSUBGPOS_have_MarkAttachmentType_flag( gpos ) ); if ( need_MarkAttachClassDef ) { OTV_LIMIT_CHECK( 8 ); table_size += 2; } else OTV_LIMIT_CHECK( 6 ); /* OpenType < 1.2 */ break; case 2: OTV_LIMIT_CHECK( 10 ); table_size += 4; break; case 3: OTV_LIMIT_CHECK( 14 ); table_size += 8; break; default: FT_INVALID_FORMAT; } otvalid->glyph_count = glyph_count; OTV_OPTIONAL_OFFSET( GlyphClassDef ); OTV_SIZE_CHECK( GlyphClassDef ); if ( GlyphClassDef ) otv_ClassDef_validate( table + GlyphClassDef, otvalid ); OTV_OPTIONAL_OFFSET( AttachListOffset ); OTV_SIZE_CHECK( AttachListOffset ); if ( AttachListOffset ) { OTV_NEST2( AttachList, AttachPoint ); OTV_RUN( table + AttachListOffset, otvalid ); } OTV_OPTIONAL_OFFSET( LigCaretListOffset ); OTV_SIZE_CHECK( LigCaretListOffset ); if ( LigCaretListOffset ) { OTV_NEST3( LigCaretList, LigGlyph, CaretValue ); OTV_RUN( table + LigCaretListOffset, otvalid ); } if ( need_MarkAttachClassDef ) { OTV_OPTIONAL_OFFSET( MarkAttachClassDef ); OTV_SIZE_CHECK( MarkAttachClassDef ); if ( MarkAttachClassDef ) otv_ClassDef_validate( table + MarkAttachClassDef, otvalid ); } if ( version > 0 ) { OTV_OPTIONAL_OFFSET( MarkGlyphSetsDef ); OTV_SIZE_CHECK( MarkGlyphSetsDef ); if ( MarkGlyphSetsDef ) otv_MarkGlyphSets_validate( table + MarkGlyphSetsDef, otvalid ); } if ( version > 2 ) { OTV_OPTIONAL_OFFSET32( itemVarStore ); OTV_SIZE_CHECK32( itemVarStore ); if ( itemVarStore ) OTV_TRACE(( " [omitting itemVarStore validation]\n" )); /* XXX */ } FT_TRACE4(( "\n" )); }
otv_BASE_validate( FT_Bytes table, FT_Validator ftvalid ) { OTV_ValidatorRec otvalidrec; OTV_Validator otvalid = &otvalidrec; FT_Bytes p = table; FT_UInt table_size; FT_UShort version; OTV_OPTIONAL_TABLE( HorizAxis ); OTV_OPTIONAL_TABLE( VertAxis ); OTV_OPTIONAL_TABLE32( itemVarStore ); otvalid->root = ftvalid; FT_TRACE3(( "validating BASE table\n" )); OTV_INIT; OTV_LIMIT_CHECK( 4 ); if ( FT_NEXT_USHORT( p ) != 1 ) /* majorVersion */ FT_INVALID_FORMAT; version = FT_NEXT_USHORT( p ); /* minorVersion */ table_size = 8; switch ( version ) { case 0: OTV_LIMIT_CHECK( 4 ); break; case 1: OTV_LIMIT_CHECK( 8 ); table_size += 4; break; default: FT_INVALID_FORMAT; } OTV_OPTIONAL_OFFSET( HorizAxis ); OTV_SIZE_CHECK( HorizAxis ); if ( HorizAxis ) otv_Axis_validate( table + HorizAxis, otvalid ); OTV_OPTIONAL_OFFSET( VertAxis ); OTV_SIZE_CHECK( VertAxis ); if ( VertAxis ) otv_Axis_validate( table + VertAxis, otvalid ); if ( version > 0 ) { OTV_OPTIONAL_OFFSET32( itemVarStore ); OTV_SIZE_CHECK32( itemVarStore ); if ( itemVarStore ) OTV_TRACE(( " [omitting itemVarStore validation]\n" )); /* XXX */ } FT_TRACE4(( "\n" )); }