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_LONG( p ); noStretchValue = FT_NEXT_LONG( p ); maximumLimit = FT_NEXT_LONG( p ); gxvalid->subtable_length = (FT_ULong)( 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; }
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_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_LONG( p ); upperLimit = FT_NEXT_LONG( 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 = (FT_ULong)( p - table ); }
FT_Stream_GetLong( FT_Stream stream ) { FT_Byte* p; FT_Long result; FT_ASSERT( stream && stream->cursor ); result = 0; p = stream->cursor; if ( p + 3 < stream->limit ) result = FT_NEXT_LONG( p ); stream->cursor = p; return result; }
FT_Stream_ReadLong( FT_Stream stream, FT_Error* error ) { FT_Byte reads[4]; FT_Byte* p = 0; FT_Long result = 0; FT_ASSERT( stream ); *error = FT_Err_Ok; if ( stream->pos + 3 < stream->size ) { if ( stream->read ) { if ( stream->read( stream, stream->pos, reads, 4L ) != 4L ) goto Fail; p = reads; } else { p = stream->base + stream->pos; } if ( p ) result = FT_NEXT_LONG( p ); } else goto Fail; stream->pos += 4; return result; Fail: FT_ERROR(( "FT_Stream_ReadLong: invalid i/o; pos = 0x%lx, size = 0x%lx\n", stream->pos, stream->size )); *error = FT_Err_Invalid_Stream_Operation; return 0; }
gxv_lcar_validate( FT_Bytes table, FT_Face face, FT_Validator ftvalid ) { FT_Bytes p = table; FT_Bytes limit = 0; GXV_ValidatorRec gxvalidrec; GXV_Validator gxvalid = &gxvalidrec; GXV_lcar_DataRec lcarrec; GXV_lcar_Data lcar = &lcarrec; FT_Fixed version; gxvalid->root = ftvalid; gxvalid->table_data = lcar; gxvalid->face = face; FT_TRACE3(( "validating `lcar' table\n" )); GXV_INIT; GXV_LIMIT_CHECK( 4 + 2 ); version = FT_NEXT_LONG( p ); GXV_LCAR_DATA( format ) = FT_NEXT_USHORT( p ); if ( version != 0x00010000UL) FT_INVALID_FORMAT; if ( GXV_LCAR_DATA( format ) > 1 ) FT_INVALID_FORMAT; gxvalid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; gxvalid->lookupval_func = gxv_lcar_LookupValue_validate; gxvalid->lookupfmt4_trans = gxv_lcar_LookupFmt4_transit; gxv_LookupTable_validate( p, limit, gxvalid ); FT_TRACE4(( "\n" )); }
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; }