00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "gxvalid.h"
00029 #include "gxvcommn.h"
00030 #include "gxvfeat.h"
00031
00032
00033
00034
00035
00036
00037
00038
00039 #undef FT_COMPONENT
00040 #define FT_COMPONENT trace_gxvfeat
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 typedef struct GXV_feat_DataRec_
00052 {
00053 FT_UInt reserved_size;
00054 FT_UShort feature;
00055 FT_UShort setting;
00056
00057 } GXV_feat_DataRec, *GXV_feat_Data;
00058
00059
00060 #define GXV_FEAT_DATA( field ) GXV_TABLE_DATA( feat, field )
00061
00062
00063 typedef enum GXV_FeatureFlagsMask_
00064 {
00065 GXV_FEAT_MASK_EXCLUSIVE_SETTINGS = 0x8000U,
00066 GXV_FEAT_MASK_DYNAMIC_DEFAULT = 0x4000,
00067 GXV_FEAT_MASK_UNUSED = 0x3F00,
00068 GXV_FEAT_MASK_DEFAULT_SETTING = 0x00FF
00069
00070 } GXV_FeatureFlagsMask;
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 static void
00082 gxv_feat_registry_validate( FT_UShort feature,
00083 FT_UShort nSettings,
00084 FT_Bool exclusive,
00085 GXV_Validator valid )
00086 {
00087 GXV_NAME_ENTER( "feature in registry" );
00088
00089 GXV_TRACE(( " (feature = %u)\n", feature ));
00090
00091 if ( feature >= gxv_feat_registry_length )
00092 {
00093 GXV_TRACE(( "feature number %d is out of range %d\n",
00094 feature, gxv_feat_registry_length ));
00095 if ( valid->root->level == FT_VALIDATE_PARANOID )
00096 FT_INVALID_DATA;
00097 goto Exit;
00098 }
00099
00100 if ( gxv_feat_registry[feature].existence == 0 )
00101 {
00102 GXV_TRACE(( "feature number %d is in defined range but doesn't exist\n",
00103 feature ));
00104 if ( valid->root->level == FT_VALIDATE_PARANOID )
00105 FT_INVALID_DATA;
00106 goto Exit;
00107 }
00108
00109 if ( gxv_feat_registry[feature].apple_reserved )
00110 {
00111
00112 GXV_TRACE(( "feature number %d is reserved by Apple\n", feature ));
00113 if ( valid->root->level >= FT_VALIDATE_TIGHT )
00114 FT_INVALID_DATA;
00115 }
00116
00117 if ( nSettings != gxv_feat_registry[feature].nSettings )
00118 {
00119 GXV_TRACE(( "feature %d: nSettings %d != defined nSettings %d\n",
00120 feature, nSettings,
00121 gxv_feat_registry[feature].nSettings ));
00122 if ( valid->root->level >= FT_VALIDATE_TIGHT )
00123 FT_INVALID_DATA;
00124 }
00125
00126 if ( exclusive != gxv_feat_registry[feature].exclusive )
00127 {
00128 GXV_TRACE(( "exclusive flag %d differs from predefined value\n",
00129 exclusive ));
00130 if ( valid->root->level >= FT_VALIDATE_TIGHT )
00131 FT_INVALID_DATA;
00132 }
00133
00134 Exit:
00135 GXV_EXIT;
00136 }
00137
00138
00139 static void
00140 gxv_feat_name_index_validate( FT_Bytes table,
00141 FT_Bytes limit,
00142 GXV_Validator valid )
00143 {
00144 FT_Bytes p = table;
00145
00146 FT_Short nameIndex;
00147
00148
00149 GXV_NAME_ENTER( "nameIndex" );
00150
00151 GXV_LIMIT_CHECK( 2 );
00152 nameIndex = FT_NEXT_SHORT ( p );
00153 GXV_TRACE(( " (nameIndex = %d)\n", nameIndex ));
00154
00155 gxv_sfntName_validate( (FT_UShort)nameIndex,
00156 255,
00157 32768U,
00158 valid );
00159
00160 GXV_EXIT;
00161 }
00162
00163
00164 static void
00165 gxv_feat_setting_validate( FT_Bytes table,
00166 FT_Bytes limit,
00167 FT_Bool exclusive,
00168 GXV_Validator valid )
00169 {
00170 FT_Bytes p = table;
00171 FT_UShort setting;
00172
00173
00174 GXV_NAME_ENTER( "setting" );
00175
00176 GXV_LIMIT_CHECK( 2 );
00177
00178 setting = FT_NEXT_USHORT( p );
00179
00180
00181 if ( exclusive && ( setting % 2 ) == 0 )
00182 FT_INVALID_DATA;
00183
00184 gxv_feat_name_index_validate( p, limit, valid );
00185
00186 GXV_FEAT_DATA( setting ) = setting;
00187
00188 GXV_EXIT;
00189 }
00190
00191
00192 static void
00193 gxv_feat_name_validate( FT_Bytes table,
00194 FT_Bytes limit,
00195 GXV_Validator valid )
00196 {
00197 FT_Bytes p = table;
00198 FT_UInt reserved_size = GXV_FEAT_DATA( reserved_size );
00199
00200 FT_UShort feature;
00201 FT_UShort nSettings;
00202 FT_ULong settingTable;
00203 FT_UShort featureFlags;
00204
00205 FT_Bool exclusive;
00206 FT_Int last_setting;
00207 FT_UInt i;
00208
00209
00210 GXV_NAME_ENTER( "name" );
00211
00212
00213 GXV_LIMIT_CHECK( 2 + 2 + 4 + 2 );
00214
00215 feature = FT_NEXT_USHORT( p );
00216 GXV_FEAT_DATA( feature ) = feature;
00217
00218 nSettings = FT_NEXT_USHORT( p );
00219 settingTable = FT_NEXT_ULONG ( p );
00220 featureFlags = FT_NEXT_USHORT( p );
00221
00222 if ( settingTable < reserved_size )
00223 FT_INVALID_OFFSET;
00224
00225 if ( valid->root->level == FT_VALIDATE_PARANOID &&
00226 ( featureFlags & GXV_FEAT_MASK_UNUSED ) == 0 )
00227 FT_INVALID_DATA;
00228
00229 exclusive = FT_BOOL( featureFlags & GXV_FEAT_MASK_EXCLUSIVE_SETTINGS );
00230 if ( exclusive )
00231 {
00232 FT_Byte dynamic_default;
00233
00234
00235 if ( featureFlags & GXV_FEAT_MASK_DYNAMIC_DEFAULT )
00236 dynamic_default = (FT_Byte)( featureFlags &
00237 GXV_FEAT_MASK_DEFAULT_SETTING );
00238 else
00239 dynamic_default = 0;
00240
00241
00242 if ( !( dynamic_default < nSettings ) )
00243 FT_INVALID_FORMAT;
00244 }
00245
00246 gxv_feat_registry_validate( feature, nSettings, exclusive, valid );
00247
00248 gxv_feat_name_index_validate( p, limit, valid );
00249
00250 p = valid->root->base + settingTable;
00251 for ( last_setting = -1, i = 0; i < nSettings; i++ )
00252 {
00253 gxv_feat_setting_validate( p, limit, exclusive, valid );
00254
00255 if ( valid->root->level == FT_VALIDATE_PARANOID &&
00256 (FT_Int)GXV_FEAT_DATA( setting ) <= last_setting )
00257 FT_INVALID_FORMAT;
00258
00259 last_setting = (FT_Int)GXV_FEAT_DATA( setting );
00260
00261 p += ( 2 + 2 );
00262 }
00263
00264 GXV_EXIT;
00265 }
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276 FT_LOCAL_DEF( void )
00277 gxv_feat_validate( FT_Bytes table,
00278 FT_Face face,
00279 FT_Validator ftvalid )
00280 {
00281 GXV_ValidatorRec validrec;
00282 GXV_Validator valid = &validrec;
00283
00284 GXV_feat_DataRec featrec;
00285 GXV_feat_Data feat = &featrec;
00286
00287 FT_Bytes p = table;
00288 FT_Bytes limit = 0;
00289
00290 FT_UInt featureNameCount;
00291
00292 FT_UInt i;
00293 FT_Int last_feature;
00294
00295
00296 valid->root = ftvalid;
00297 valid->table_data = feat;
00298 valid->face = face;
00299
00300 FT_TRACE3(( "validating `feat' table\n" ));
00301 GXV_INIT;
00302
00303 feat->reserved_size = 0;
00304
00305
00306 GXV_LIMIT_CHECK( 4 + 2 + 2 + 4 );
00307 feat->reserved_size += 4 + 2 + 2 + 4;
00308
00309 if ( FT_NEXT_ULONG( p ) != 0x00010000UL )
00310 FT_INVALID_FORMAT;
00311
00312 featureNameCount = FT_NEXT_USHORT( p );
00313 GXV_TRACE(( " (featureNameCount = %d)\n", featureNameCount ));
00314
00315 if ( valid->root->level != FT_VALIDATE_PARANOID )
00316 p += 6;
00317 else
00318 {
00319 if ( FT_NEXT_USHORT( p ) != 0 )
00320 FT_INVALID_DATA;
00321
00322 if ( FT_NEXT_ULONG( p ) != 0 )
00323 FT_INVALID_DATA;
00324 }
00325
00326 feat->reserved_size += featureNameCount * ( 2 + 2 + 4 + 2 + 2 );
00327
00328 for ( last_feature = -1, i = 0; i < featureNameCount; i++ )
00329 {
00330 gxv_feat_name_validate( p, limit, valid );
00331
00332 if ( valid->root->level == FT_VALIDATE_PARANOID &&
00333 (FT_Int)GXV_FEAT_DATA( feature ) <= last_feature )
00334 FT_INVALID_FORMAT;
00335
00336 last_feature = GXV_FEAT_DATA( feature );
00337 p += 2 + 2 + 4 + 2 + 2;
00338 }
00339
00340 FT_TRACE4(( "\n" ));
00341 }
00342
00343
00344