00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "otvalid.h"
00022 #include "otvcommn.h"
00023 #include "otvgpos.h"
00024
00025
00026
00027
00028
00029
00030
00031
00032 #undef FT_COMPONENT
00033 #define FT_COMPONENT trace_otvmath
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 static void
00046 otv_MathConstants_validate( FT_Bytes table,
00047 OTV_Validator valid )
00048 {
00049 FT_Bytes p = table;
00050 FT_UInt i;
00051 FT_UInt table_size;
00052
00053 OTV_OPTIONAL_TABLE( DeviceTableOffset );
00054
00055
00056 OTV_NAME_ENTER( "MathConstants" );
00057
00058
00059 OTV_LIMIT_CHECK( 2 * ( 56 + 51 ) );
00060 table_size = 2 * ( 56 + 51 );
00061
00062 p += 4 * 2;
00063 for ( i = 0; i < 51; ++i )
00064 {
00065 p += 2;
00066 OTV_OPTIONAL_OFFSET( DeviceTableOffset );
00067 OTV_SIZE_CHECK( DeviceTableOffset );
00068 if ( DeviceTableOffset )
00069 otv_Device_validate( table + DeviceTableOffset, valid );
00070 }
00071
00072 OTV_EXIT;
00073 }
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 static void
00086 otv_MathItalicsCorrectionInfo_validate( FT_Bytes table,
00087 OTV_Validator valid,
00088 FT_Int isItalic )
00089 {
00090 FT_Bytes p = table;
00091 FT_UInt i, cnt, table_size ;
00092
00093 OTV_OPTIONAL_TABLE( Coverage );
00094 OTV_OPTIONAL_TABLE( DeviceTableOffset );
00095
00096 FT_UNUSED( isItalic );
00097
00098
00099 OTV_NAME_ENTER( isItalic ? "MathItalicsCorrectionInfo"
00100 : "MathTopAccentAttachment" );
00101
00102 OTV_LIMIT_CHECK( 4 );
00103
00104 OTV_OPTIONAL_OFFSET( Coverage );
00105 cnt = FT_NEXT_USHORT( p );
00106
00107 OTV_LIMIT_CHECK( 4 * cnt );
00108 table_size = 4 + 4 * cnt;
00109
00110 OTV_SIZE_CHECK( Coverage );
00111 otv_Coverage_validate( table + Coverage, valid, cnt );
00112
00113 for ( i = 0; i < cnt; ++i )
00114 {
00115 p += 2;
00116 OTV_OPTIONAL_OFFSET( DeviceTableOffset );
00117 OTV_SIZE_CHECK( DeviceTableOffset );
00118 if ( DeviceTableOffset )
00119 otv_Device_validate( table + DeviceTableOffset, valid );
00120 }
00121
00122 OTV_EXIT;
00123 }
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134 static void
00135 otv_MathKern_validate( FT_Bytes table,
00136 OTV_Validator valid )
00137 {
00138 FT_Bytes p = table;
00139 FT_UInt i, cnt, table_size;
00140
00141 OTV_OPTIONAL_TABLE( DeviceTableOffset );
00142
00143
00144
00145
00146 OTV_LIMIT_CHECK( 2 );
00147
00148 cnt = FT_NEXT_USHORT( p );
00149
00150 OTV_LIMIT_CHECK( 4 * cnt + 2 );
00151 table_size = 4 + 4 * cnt;
00152
00153
00154 for ( i = 0; i < cnt; ++i )
00155 {
00156 p += 2;
00157 OTV_OPTIONAL_OFFSET( DeviceTableOffset );
00158 OTV_SIZE_CHECK( DeviceTableOffset );
00159 if ( DeviceTableOffset )
00160 otv_Device_validate( table + DeviceTableOffset, valid );
00161 }
00162
00163
00164 for ( i = 0; i < cnt + 1; ++i )
00165 {
00166 p += 2;
00167 OTV_OPTIONAL_OFFSET( DeviceTableOffset );
00168 OTV_SIZE_CHECK( DeviceTableOffset );
00169 if ( DeviceTableOffset )
00170 otv_Device_validate( table + DeviceTableOffset, valid );
00171 }
00172
00173 OTV_EXIT;
00174 }
00175
00176
00177 static void
00178 otv_MathKernInfo_validate( FT_Bytes table,
00179 OTV_Validator valid )
00180 {
00181 FT_Bytes p = table;
00182 FT_UInt i, j, cnt, table_size;
00183
00184 OTV_OPTIONAL_TABLE( Coverage );
00185 OTV_OPTIONAL_TABLE( MKRecordOffset );
00186
00187
00188 OTV_NAME_ENTER( "MathKernInfo" );
00189
00190 OTV_LIMIT_CHECK( 4 );
00191
00192 OTV_OPTIONAL_OFFSET( Coverage );
00193 cnt = FT_NEXT_USHORT( p );
00194
00195 OTV_LIMIT_CHECK( 8 * cnt );
00196 table_size = 4 + 8 * cnt;
00197
00198 OTV_SIZE_CHECK( Coverage );
00199 otv_Coverage_validate( table + Coverage, valid, cnt );
00200
00201 for ( i = 0; i < cnt; ++i )
00202 {
00203 for ( j = 0; j < 4; ++j )
00204 {
00205 OTV_OPTIONAL_OFFSET( MKRecordOffset );
00206 OTV_SIZE_CHECK( MKRecordOffset );
00207 if ( MKRecordOffset )
00208 otv_MathKern_validate( table + MKRecordOffset, valid );
00209 }
00210 }
00211
00212 OTV_EXIT;
00213 }
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 static void
00225 otv_MathGlyphInfo_validate( FT_Bytes table,
00226 OTV_Validator valid )
00227 {
00228 FT_Bytes p = table;
00229 FT_UInt MathItalicsCorrectionInfo, MathTopAccentAttachment;
00230 FT_UInt ExtendedShapeCoverage, MathKernInfo;
00231
00232
00233 OTV_NAME_ENTER( "MathGlyphInfo" );
00234
00235 OTV_LIMIT_CHECK( 8 );
00236
00237 MathItalicsCorrectionInfo = FT_NEXT_USHORT( p );
00238 MathTopAccentAttachment = FT_NEXT_USHORT( p );
00239 ExtendedShapeCoverage = FT_NEXT_USHORT( p );
00240 MathKernInfo = FT_NEXT_USHORT( p );
00241
00242 if ( MathItalicsCorrectionInfo )
00243 otv_MathItalicsCorrectionInfo_validate(
00244 table + MathItalicsCorrectionInfo, valid, TRUE );
00245
00246
00247 if ( MathTopAccentAttachment )
00248 otv_MathItalicsCorrectionInfo_validate(
00249 table + MathTopAccentAttachment, valid, FALSE );
00250
00251 if ( ExtendedShapeCoverage ) {
00252 OTV_NAME_ENTER( "ExtendedShapeCoverage" );
00253 otv_Coverage_validate( table + ExtendedShapeCoverage, valid, -1 );
00254 OTV_EXIT;
00255 }
00256
00257 if ( MathKernInfo )
00258 otv_MathKernInfo_validate( table + MathKernInfo, valid );
00259
00260 OTV_EXIT;
00261 }
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272 static void
00273 otv_GlyphAssembly_validate( FT_Bytes table,
00274 OTV_Validator valid )
00275 {
00276 FT_Bytes p = table;
00277 FT_UInt pcnt, table_size;
00278 FT_UInt i;
00279
00280 OTV_OPTIONAL_TABLE( DeviceTableOffset );
00281
00282
00283
00284
00285 OTV_LIMIT_CHECK( 6 );
00286
00287 p += 2;
00288 OTV_OPTIONAL_OFFSET( DeviceTableOffset );
00289 pcnt = FT_NEXT_USHORT( p );
00290
00291 OTV_LIMIT_CHECK( 8 * pcnt );
00292 table_size = 6 + 8 * pcnt;
00293
00294 OTV_SIZE_CHECK( DeviceTableOffset );
00295 if ( DeviceTableOffset )
00296 otv_Device_validate( table + DeviceTableOffset, valid );
00297
00298 for ( i = 0; i < pcnt; ++i )
00299 {
00300 FT_UInt gid;
00301
00302
00303 gid = FT_NEXT_USHORT( p );
00304 if ( gid >= valid->glyph_count )
00305 FT_INVALID_GLYPH_ID;
00306 p += 2*4;
00307 }
00308
00309
00310 }
00311
00312
00313 static void
00314 otv_MathGlyphConstruction_validate( FT_Bytes table,
00315 OTV_Validator valid )
00316 {
00317 FT_Bytes p = table;
00318 FT_UInt vcnt, table_size;
00319 FT_UInt i;
00320
00321 OTV_OPTIONAL_TABLE( GlyphAssembly );
00322
00323
00324
00325
00326 OTV_LIMIT_CHECK( 4 );
00327
00328 OTV_OPTIONAL_OFFSET( GlyphAssembly );
00329 vcnt = FT_NEXT_USHORT( p );
00330
00331 OTV_LIMIT_CHECK( 4 * vcnt );
00332 table_size = 4 + 4 * vcnt;
00333
00334 for ( i = 0; i < vcnt; ++i )
00335 {
00336 FT_UInt gid;
00337
00338
00339 gid = FT_NEXT_USHORT( p );
00340 if ( gid >= valid->glyph_count )
00341 FT_INVALID_GLYPH_ID;
00342 p += 2;
00343 }
00344
00345 OTV_SIZE_CHECK( GlyphAssembly );
00346 if ( GlyphAssembly )
00347 otv_GlyphAssembly_validate( table+GlyphAssembly, valid );
00348
00349
00350 }
00351
00352
00353 static void
00354 otv_MathVariants_validate( FT_Bytes table,
00355 OTV_Validator valid )
00356 {
00357 FT_Bytes p = table;
00358 FT_UInt vcnt, hcnt, i, table_size;
00359
00360 OTV_OPTIONAL_TABLE( VCoverage );
00361 OTV_OPTIONAL_TABLE( HCoverage );
00362 OTV_OPTIONAL_TABLE( Offset );
00363
00364
00365 OTV_NAME_ENTER( "MathVariants" );
00366
00367 OTV_LIMIT_CHECK( 10 );
00368
00369 p += 2;
00370 OTV_OPTIONAL_OFFSET( VCoverage );
00371 OTV_OPTIONAL_OFFSET( HCoverage );
00372 vcnt = FT_NEXT_USHORT( p );
00373 hcnt = FT_NEXT_USHORT( p );
00374
00375 OTV_LIMIT_CHECK( 2 * vcnt + 2 * hcnt );
00376 table_size = 10 + 2 * vcnt + 2 * hcnt;
00377
00378 OTV_SIZE_CHECK( VCoverage );
00379 if ( VCoverage )
00380 otv_Coverage_validate( table + VCoverage, valid, vcnt );
00381
00382 OTV_SIZE_CHECK( HCoverage );
00383 if ( HCoverage )
00384 otv_Coverage_validate( table + HCoverage, valid, hcnt );
00385
00386 for ( i = 0; i < vcnt; ++i )
00387 {
00388 OTV_OPTIONAL_OFFSET( Offset );
00389 OTV_SIZE_CHECK( Offset );
00390 otv_MathGlyphConstruction_validate( table + Offset, valid );
00391 }
00392
00393 for ( i = 0; i < hcnt; ++i )
00394 {
00395 OTV_OPTIONAL_OFFSET( Offset );
00396 OTV_SIZE_CHECK( Offset );
00397 otv_MathGlyphConstruction_validate( table + Offset, valid );
00398 }
00399
00400 OTV_EXIT;
00401 }
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414 FT_LOCAL_DEF( void )
00415 otv_MATH_validate( FT_Bytes table,
00416 FT_UInt glyph_count,
00417 FT_Validator ftvalid )
00418 {
00419 OTV_ValidatorRec validrec;
00420 OTV_Validator valid = &validrec;
00421 FT_Bytes p = table;
00422 FT_UInt MathConstants, MathGlyphInfo, MathVariants;
00423
00424
00425 valid->root = ftvalid;
00426
00427 FT_TRACE3(( "validating MATH table\n" ));
00428 OTV_INIT;
00429
00430 OTV_LIMIT_CHECK( 10 );
00431
00432 if ( FT_NEXT_ULONG( p ) != 0x10000UL )
00433 FT_INVALID_FORMAT;
00434
00435 MathConstants = FT_NEXT_USHORT( p );
00436 MathGlyphInfo = FT_NEXT_USHORT( p );
00437 MathVariants = FT_NEXT_USHORT( p );
00438
00439 valid->glyph_count = glyph_count;
00440
00441 otv_MathConstants_validate( table + MathConstants,
00442 valid );
00443 otv_MathGlyphInfo_validate( table + MathGlyphInfo,
00444 valid );
00445 otv_MathVariants_validate ( table + MathVariants,
00446 valid );
00447
00448 FT_TRACE4(( "\n" ));
00449 }
00450
00451
00452