static void gxv_trak_trackData_validate( FT_Bytes table, FT_Bytes limit, GXV_Validator gxvalid ) { FT_Bytes p = table; FT_UShort nTracks; FT_UShort nSizes; FT_ULong sizeTableOffset; GXV_ODTECT( 4, odtect ); GXV_ODTECT_INIT( odtect ); GXV_NAME_ENTER( "trackData" ); /* read the header of trackData */ GXV_LIMIT_CHECK( 2 + 2 + 4 ); nTracks = FT_NEXT_USHORT( p ); nSizes = FT_NEXT_USHORT( p ); sizeTableOffset = FT_NEXT_ULONG( p ); gxv_odtect_add_range( table, (FT_ULong)( p - table ), "trackData header", odtect ); /* validate trackTable */ gxv_trak_trackTable_validate( p, limit, nTracks, gxvalid ); gxv_odtect_add_range( p, gxvalid->subtable_length, "trackTable", odtect ); /* sizeTable is array of FT_Fixed, don't check contents */ p = gxvalid->root->base + sizeTableOffset; GXV_LIMIT_CHECK( nSizes * 4 ); gxv_odtect_add_range( p, nSizes * 4, "sizeTable", odtect ); /* validate trackValueOffet */ p = gxvalid->root->base + GXV_TRAK_DATA( trackValueOffset_min ); if ( limit - p < nTracks * nSizes * 2 ) GXV_TRACE(( "too short trackValue array\n" )); p = gxvalid->root->base + GXV_TRAK_DATA( trackValueOffset_max ); GXV_LIMIT_CHECK( nSizes * 2 ); gxv_odtect_add_range( gxvalid->root->base + GXV_TRAK_DATA( trackValueOffset_min ), GXV_TRAK_DATA( trackValueOffset_max ) - GXV_TRAK_DATA( trackValueOffset_min ) + nSizes * 2, "trackValue array", odtect ); gxv_odtect_validate( odtect, gxvalid ); GXV_EXIT; }
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; }
static void gxv_trak_trackTable_validate( FT_Bytes table, FT_Bytes limit, FT_UShort nTracks, GXV_Validator valid ) { FT_Bytes p = table; FT_Fixed track; FT_UShort nameIndex; FT_UShort offset; FT_UShort i; GXV_NAME_ENTER( "trackTable" ); GXV_TRAK_DATA( trackValueOffset_min ) = 0xFFFFU; GXV_TRAK_DATA( trackValueOffset_max ) = 0x0000; for ( i = 0; i < nTracks; i ++ ) { GXV_LIMIT_CHECK( 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, valid ); } valid->subtable_length = p - table; GXV_EXIT; }