00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "otvcommn.h"
00020
00021
00022
00023
00024
00025
00026
00027
00028 #undef FT_COMPONENT
00029 #define FT_COMPONENT trace_otvcommon
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 FT_LOCAL_DEF( void )
00041 otv_Coverage_validate( FT_Bytes table,
00042 OTV_Validator valid,
00043 FT_Int expected_count )
00044 {
00045 FT_Bytes p = table;
00046 FT_UInt CoverageFormat;
00047 FT_UInt total = 0;
00048
00049
00050 OTV_NAME_ENTER( "Coverage" );
00051
00052 OTV_LIMIT_CHECK( 4 );
00053 CoverageFormat = FT_NEXT_USHORT( p );
00054
00055 OTV_TRACE(( " (format %d)\n", CoverageFormat ));
00056
00057 switch ( CoverageFormat )
00058 {
00059 case 1:
00060 {
00061 FT_UInt GlyphCount;
00062 FT_UInt i;
00063
00064
00065 GlyphCount = FT_NEXT_USHORT( p );
00066
00067 OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount ));
00068
00069 OTV_LIMIT_CHECK( GlyphCount * 2 );
00070
00071 for ( i = 0; i < GlyphCount; ++i )
00072 {
00073 FT_UInt gid;
00074
00075
00076 gid = FT_NEXT_USHORT( p );
00077 if ( gid >= valid->glyph_count )
00078 FT_INVALID_GLYPH_ID;
00079 }
00080
00081 total = GlyphCount;
00082 }
00083 break;
00084
00085 case 2:
00086 {
00087 FT_UInt n, RangeCount;
00088 FT_UInt Start, End, StartCoverageIndex, last = 0;
00089
00090
00091 RangeCount = FT_NEXT_USHORT( p );
00092
00093 OTV_TRACE(( " (RangeCount = %d)\n", RangeCount ));
00094
00095 OTV_LIMIT_CHECK( RangeCount * 6 );
00096
00097
00098 for ( n = 0; n < RangeCount; n++ )
00099 {
00100 Start = FT_NEXT_USHORT( p );
00101 End = FT_NEXT_USHORT( p );
00102 StartCoverageIndex = FT_NEXT_USHORT( p );
00103
00104 if ( Start > End || StartCoverageIndex != total )
00105 FT_INVALID_DATA;
00106
00107 if ( End >= valid->glyph_count )
00108 FT_INVALID_GLYPH_ID;
00109
00110 if ( n > 0 && Start <= last )
00111 FT_INVALID_DATA;
00112
00113 total += End - Start + 1;
00114 last = End;
00115 }
00116 }
00117 break;
00118
00119 default:
00120 FT_INVALID_FORMAT;
00121 }
00122
00123
00124
00125
00126 if ( expected_count != -1 && (FT_UInt)expected_count != total )
00127 FT_INVALID_DATA;
00128
00129 OTV_EXIT;
00130 }
00131
00132
00133 FT_LOCAL_DEF( FT_UInt )
00134 otv_Coverage_get_first( FT_Bytes table )
00135 {
00136 FT_Bytes p = table;
00137
00138
00139 p += 4;
00140
00141 return FT_NEXT_USHORT( p );
00142 }
00143
00144
00145 FT_LOCAL_DEF( FT_UInt )
00146 otv_Coverage_get_last( FT_Bytes table )
00147 {
00148 FT_Bytes p = table;
00149 FT_UInt CoverageFormat = FT_NEXT_USHORT( p );
00150 FT_UInt count = FT_NEXT_USHORT( p );
00151 FT_UInt result = 0;
00152
00153
00154 switch ( CoverageFormat )
00155 {
00156 case 1:
00157 p += ( count - 1 ) * 2;
00158 result = FT_NEXT_USHORT( p );
00159 break;
00160
00161 case 2:
00162 p += ( count - 1 ) * 6 + 2;
00163 result = FT_NEXT_USHORT( p );
00164 break;
00165
00166 default:
00167 ;
00168 }
00169
00170 return result;
00171 }
00172
00173
00174 FT_LOCAL_DEF( FT_UInt )
00175 otv_Coverage_get_count( FT_Bytes table )
00176 {
00177 FT_Bytes p = table;
00178 FT_UInt CoverageFormat = FT_NEXT_USHORT( p );
00179 FT_UInt count = FT_NEXT_USHORT( p );
00180 FT_UInt result = 0;
00181
00182
00183 switch ( CoverageFormat )
00184 {
00185 case 1:
00186 return count;
00187
00188 case 2:
00189 {
00190 FT_UInt Start, End;
00191
00192
00193 for ( ; count > 0; count-- )
00194 {
00195 Start = FT_NEXT_USHORT( p );
00196 End = FT_NEXT_USHORT( p );
00197 p += 2;
00198
00199 result += End - Start + 1;
00200 }
00201 }
00202 break;
00203
00204 default:
00205 ;
00206 }
00207
00208 return result;
00209 }
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220 FT_LOCAL_DEF( void )
00221 otv_ClassDef_validate( FT_Bytes table,
00222 OTV_Validator valid )
00223 {
00224 FT_Bytes p = table;
00225 FT_UInt ClassFormat;
00226
00227
00228 OTV_NAME_ENTER( "ClassDef" );
00229
00230 OTV_LIMIT_CHECK( 4 );
00231 ClassFormat = FT_NEXT_USHORT( p );
00232
00233 OTV_TRACE(( " (format %d)\n", ClassFormat ));
00234
00235 switch ( ClassFormat )
00236 {
00237 case 1:
00238 {
00239 FT_UInt StartGlyph;
00240 FT_UInt GlyphCount;
00241
00242
00243 OTV_LIMIT_CHECK( 4 );
00244
00245 StartGlyph = FT_NEXT_USHORT( p );
00246 GlyphCount = FT_NEXT_USHORT( p );
00247
00248 OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount ));
00249
00250 OTV_LIMIT_CHECK( GlyphCount * 2 );
00251
00252 if ( StartGlyph + GlyphCount - 1 >= valid->glyph_count )
00253 FT_INVALID_GLYPH_ID;
00254 }
00255 break;
00256
00257 case 2:
00258 {
00259 FT_UInt n, ClassRangeCount;
00260 FT_UInt Start, End, last = 0;
00261
00262
00263 ClassRangeCount = FT_NEXT_USHORT( p );
00264
00265 OTV_TRACE(( " (ClassRangeCount = %d)\n", ClassRangeCount ));
00266
00267 OTV_LIMIT_CHECK( ClassRangeCount * 6 );
00268
00269
00270 for ( n = 0; n < ClassRangeCount; n++ )
00271 {
00272 Start = FT_NEXT_USHORT( p );
00273 End = FT_NEXT_USHORT( p );
00274 p += 2;
00275
00276 if ( Start > End || ( n > 0 && Start <= last ) )
00277 FT_INVALID_DATA;
00278
00279 if ( End >= valid->glyph_count )
00280 FT_INVALID_GLYPH_ID;
00281
00282 last = End;
00283 }
00284 }
00285 break;
00286
00287 default:
00288 FT_INVALID_FORMAT;
00289 }
00290
00291
00292
00293
00294 OTV_EXIT;
00295 }
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306 FT_LOCAL_DEF( void )
00307 otv_Device_validate( FT_Bytes table,
00308 OTV_Validator valid )
00309 {
00310 FT_Bytes p = table;
00311 FT_UInt StartSize, EndSize, DeltaFormat, count;
00312
00313
00314 OTV_NAME_ENTER( "Device" );
00315
00316 OTV_LIMIT_CHECK( 8 );
00317 StartSize = FT_NEXT_USHORT( p );
00318 EndSize = FT_NEXT_USHORT( p );
00319 DeltaFormat = FT_NEXT_USHORT( p );
00320
00321 if ( DeltaFormat < 1 || DeltaFormat > 3 )
00322 FT_INVALID_FORMAT;
00323
00324 if ( EndSize < StartSize )
00325 FT_INVALID_DATA;
00326
00327 count = EndSize - StartSize + 1;
00328 OTV_LIMIT_CHECK( ( 1 << DeltaFormat ) * count / 8 );
00329
00330 OTV_EXIT;
00331 }
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345 FT_LOCAL_DEF( void )
00346 otv_Lookup_validate( FT_Bytes table,
00347 OTV_Validator valid )
00348 {
00349 FT_Bytes p = table;
00350 FT_UInt LookupType, SubTableCount;
00351 OTV_Validate_Func validate;
00352
00353
00354 OTV_NAME_ENTER( "Lookup" );
00355
00356 OTV_LIMIT_CHECK( 6 );
00357 LookupType = FT_NEXT_USHORT( p );
00358 p += 2;
00359 SubTableCount = FT_NEXT_USHORT( p );
00360
00361 OTV_TRACE(( " (type %d)\n", LookupType ));
00362
00363 if ( LookupType == 0 || LookupType > valid->type_count )
00364 FT_INVALID_DATA;
00365
00366 validate = valid->type_funcs[LookupType - 1];
00367
00368 OTV_TRACE(( " (SubTableCount = %d)\n", SubTableCount ));
00369
00370 OTV_LIMIT_CHECK( SubTableCount * 2 );
00371
00372
00373 for ( ; SubTableCount > 0; SubTableCount-- )
00374 validate( table + FT_NEXT_USHORT( p ), valid );
00375
00376 OTV_EXIT;
00377 }
00378
00379
00380
00381
00382 FT_LOCAL_DEF( void )
00383 otv_LookupList_validate( FT_Bytes table,
00384 OTV_Validator valid )
00385 {
00386 FT_Bytes p = table;
00387 FT_UInt LookupCount;
00388
00389
00390 OTV_NAME_ENTER( "LookupList" );
00391
00392 OTV_LIMIT_CHECK( 2 );
00393 LookupCount = FT_NEXT_USHORT( p );
00394
00395 OTV_TRACE(( " (LookupCount = %d)\n", LookupCount ));
00396
00397 OTV_LIMIT_CHECK( LookupCount * 2 );
00398
00399 valid->lookup_count = LookupCount;
00400
00401
00402 for ( ; LookupCount > 0; LookupCount-- )
00403 otv_Lookup_validate( table + FT_NEXT_USHORT( p ), valid );
00404
00405 OTV_EXIT;
00406 }
00407
00408
00409 static FT_UInt
00410 otv_LookupList_get_count( FT_Bytes table )
00411 {
00412 return FT_NEXT_USHORT( table );
00413 }
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426 FT_LOCAL_DEF( void )
00427 otv_Feature_validate( FT_Bytes table,
00428 OTV_Validator valid )
00429 {
00430 FT_Bytes p = table;
00431 FT_UInt LookupCount;
00432
00433
00434 OTV_NAME_ENTER( "Feature" );
00435
00436 OTV_LIMIT_CHECK( 4 );
00437 p += 2;
00438 LookupCount = FT_NEXT_USHORT( p );
00439
00440 OTV_TRACE(( " (LookupCount = %d)\n", LookupCount ));
00441
00442 OTV_LIMIT_CHECK( LookupCount * 2 );
00443
00444
00445 for ( ; LookupCount > 0; LookupCount-- )
00446 if ( FT_NEXT_USHORT( p ) >= valid->lookup_count )
00447 FT_INVALID_DATA;
00448
00449 OTV_EXIT;
00450 }
00451
00452
00453 static FT_UInt
00454 otv_Feature_get_count( FT_Bytes table )
00455 {
00456 return FT_NEXT_USHORT( table );
00457 }
00458
00459
00460
00461
00462 FT_LOCAL_DEF( void )
00463 otv_FeatureList_validate( FT_Bytes table,
00464 FT_Bytes lookups,
00465 OTV_Validator valid )
00466 {
00467 FT_Bytes p = table;
00468 FT_UInt FeatureCount;
00469
00470
00471 OTV_NAME_ENTER( "FeatureList" );
00472
00473 OTV_LIMIT_CHECK( 2 );
00474 FeatureCount = FT_NEXT_USHORT( p );
00475
00476 OTV_TRACE(( " (FeatureCount = %d)\n", FeatureCount ));
00477
00478 OTV_LIMIT_CHECK( FeatureCount * 2 );
00479
00480 valid->lookup_count = otv_LookupList_get_count( lookups );
00481
00482
00483 for ( ; FeatureCount > 0; FeatureCount-- )
00484 {
00485 p += 4;
00486
00487
00488 otv_Feature_validate( table + FT_NEXT_USHORT( p ), valid );
00489 }
00490
00491 OTV_EXIT;
00492 }
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506 FT_LOCAL_DEF( void )
00507 otv_LangSys_validate( FT_Bytes table,
00508 OTV_Validator valid )
00509 {
00510 FT_Bytes p = table;
00511 FT_UInt ReqFeatureIndex;
00512 FT_UInt FeatureCount;
00513
00514
00515 OTV_NAME_ENTER( "LangSys" );
00516
00517 OTV_LIMIT_CHECK( 6 );
00518 p += 2;
00519 ReqFeatureIndex = FT_NEXT_USHORT( p );
00520 FeatureCount = FT_NEXT_USHORT( p );
00521
00522 OTV_TRACE(( " (ReqFeatureIndex = %d)\n", ReqFeatureIndex ));
00523 OTV_TRACE(( " (FeatureCount = %d)\n", FeatureCount ));
00524
00525 if ( ReqFeatureIndex != 0xFFFFU && ReqFeatureIndex >= valid->extra1 )
00526 FT_INVALID_DATA;
00527
00528 OTV_LIMIT_CHECK( FeatureCount * 2 );
00529
00530
00531 for ( ; FeatureCount > 0; FeatureCount-- )
00532 if ( FT_NEXT_USHORT( p ) >= valid->extra1 )
00533 FT_INVALID_DATA;
00534
00535 OTV_EXIT;
00536 }
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547 FT_LOCAL_DEF( void )
00548 otv_Script_validate( FT_Bytes table,
00549 OTV_Validator valid )
00550 {
00551 FT_UInt DefaultLangSys, LangSysCount;
00552 FT_Bytes p = table;
00553
00554
00555 OTV_NAME_ENTER( "Script" );
00556
00557 OTV_LIMIT_CHECK( 4 );
00558 DefaultLangSys = FT_NEXT_USHORT( p );
00559 LangSysCount = FT_NEXT_USHORT( p );
00560
00561 OTV_TRACE(( " (LangSysCount = %d)\n", LangSysCount ));
00562
00563 if ( DefaultLangSys != 0 )
00564 otv_LangSys_validate( table + DefaultLangSys, valid );
00565
00566 OTV_LIMIT_CHECK( LangSysCount * 6 );
00567
00568
00569 for ( ; LangSysCount > 0; LangSysCount-- )
00570 {
00571 p += 4;
00572
00573
00574 otv_LangSys_validate( table + FT_NEXT_USHORT( p ), valid );
00575 }
00576
00577 OTV_EXIT;
00578 }
00579
00580
00581
00582
00583 FT_LOCAL_DEF( void )
00584 otv_ScriptList_validate( FT_Bytes table,
00585 FT_Bytes features,
00586 OTV_Validator valid )
00587 {
00588 FT_UInt ScriptCount;
00589 FT_Bytes p = table;
00590
00591
00592 OTV_NAME_ENTER( "ScriptList" );
00593
00594 OTV_LIMIT_CHECK( 2 );
00595 ScriptCount = FT_NEXT_USHORT( p );
00596
00597 OTV_TRACE(( " (ScriptCount = %d)\n", ScriptCount ));
00598
00599 OTV_LIMIT_CHECK( ScriptCount * 6 );
00600
00601 valid->extra1 = otv_Feature_get_count( features );
00602
00603
00604 for ( ; ScriptCount > 0; ScriptCount-- )
00605 {
00606 p += 4;
00607
00608 otv_Script_validate( table + FT_NEXT_USHORT( p ), valid );
00609 }
00610
00611 OTV_EXIT;
00612 }
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641 FT_LOCAL_DEF( void )
00642 otv_x_Ox( FT_Bytes table,
00643 OTV_Validator valid )
00644 {
00645 FT_Bytes p = table;
00646 FT_UInt Count;
00647 OTV_Validate_Func func;
00648
00649
00650 OTV_ENTER;
00651
00652 OTV_LIMIT_CHECK( 2 );
00653 Count = FT_NEXT_USHORT( p );
00654
00655 OTV_TRACE(( " (Count = %d)\n", Count ));
00656
00657 OTV_LIMIT_CHECK( Count * 2 );
00658
00659 valid->nesting_level++;
00660 func = valid->func[valid->nesting_level];
00661
00662 for ( ; Count > 0; Count-- )
00663 func( table + FT_NEXT_USHORT( p ), valid );
00664
00665 valid->nesting_level--;
00666
00667 OTV_EXIT;
00668 }
00669
00670
00671 FT_LOCAL_DEF( void )
00672 otv_u_C_x_Ox( FT_Bytes table,
00673 OTV_Validator valid )
00674 {
00675 FT_Bytes p = table;
00676 FT_UInt Count, Coverage;
00677 OTV_Validate_Func func;
00678
00679
00680 OTV_ENTER;
00681
00682 p += 2;
00683
00684 OTV_LIMIT_CHECK( 4 );
00685 Coverage = FT_NEXT_USHORT( p );
00686 Count = FT_NEXT_USHORT( p );
00687
00688 OTV_TRACE(( " (Count = %d)\n", Count ));
00689
00690 otv_Coverage_validate( table + Coverage, valid, Count );
00691
00692 OTV_LIMIT_CHECK( Count * 2 );
00693
00694 valid->nesting_level++;
00695 func = valid->func[valid->nesting_level];
00696
00697 for ( ; Count > 0; Count-- )
00698 func( table + FT_NEXT_USHORT( p ), valid );
00699
00700 valid->nesting_level--;
00701
00702 OTV_EXIT;
00703 }
00704
00705
00706
00707
00708 FT_LOCAL_DEF( void )
00709 otv_x_ux( FT_Bytes table,
00710 OTV_Validator valid )
00711 {
00712 FT_Bytes p = table;
00713 FT_UInt Count;
00714
00715
00716 OTV_ENTER;
00717
00718 OTV_LIMIT_CHECK( 2 );
00719 Count = FT_NEXT_USHORT( p );
00720
00721 OTV_TRACE(( " (Count = %d)\n", Count ));
00722
00723 OTV_LIMIT_CHECK( Count * 2 );
00724
00725 if ( valid->extra1 )
00726 {
00727 for ( ; Count > 0; Count-- )
00728 if ( FT_NEXT_USHORT( p ) >= valid->extra1 )
00729 FT_INVALID_DATA;
00730 }
00731
00732 OTV_EXIT;
00733 }
00734
00735
00736
00737
00738
00739
00740
00741 FT_LOCAL_DEF( void )
00742 otv_x_y_ux_sy( FT_Bytes table,
00743 OTV_Validator valid )
00744 {
00745 FT_Bytes p = table;
00746 FT_UInt Count1, Count2;
00747
00748
00749 OTV_ENTER;
00750
00751 OTV_LIMIT_CHECK( 4 );
00752 Count1 = FT_NEXT_USHORT( p );
00753 Count2 = FT_NEXT_USHORT( p );
00754
00755 OTV_TRACE(( " (Count1 = %d)\n", Count1 ));
00756 OTV_TRACE(( " (Count2 = %d)\n", Count2 ));
00757
00758 if ( Count1 == 0 )
00759 FT_INVALID_DATA;
00760
00761 OTV_LIMIT_CHECK( ( Count1 - 1 ) * 2 + Count2 * 4 );
00762 p += ( Count1 - 1 ) * 2;
00763
00764 for ( ; Count2 > 0; Count2-- )
00765 {
00766 if ( FT_NEXT_USHORT( p ) >= Count1 )
00767 FT_INVALID_DATA;
00768
00769 if ( FT_NEXT_USHORT( p ) >= valid->extra1 )
00770 FT_INVALID_DATA;
00771 }
00772
00773 OTV_EXIT;
00774 }
00775
00776
00777
00778
00779
00780
00781
00782 FT_LOCAL_DEF( void )
00783 otv_x_ux_y_uy_z_uz_p_sp( FT_Bytes table,
00784 OTV_Validator valid )
00785 {
00786 FT_Bytes p = table;
00787 FT_UInt BacktrackCount, InputCount, LookaheadCount;
00788 FT_UInt Count;
00789
00790
00791 OTV_ENTER;
00792
00793 OTV_LIMIT_CHECK( 2 );
00794 BacktrackCount = FT_NEXT_USHORT( p );
00795
00796 OTV_TRACE(( " (BacktrackCount = %d)\n", BacktrackCount ));
00797
00798 OTV_LIMIT_CHECK( BacktrackCount * 2 + 2 );
00799 p += BacktrackCount * 2;
00800
00801 InputCount = FT_NEXT_USHORT( p );
00802 if ( InputCount == 0 )
00803 FT_INVALID_DATA;
00804
00805 OTV_TRACE(( " (InputCount = %d)\n", InputCount ));
00806
00807 OTV_LIMIT_CHECK( InputCount * 2 );
00808 p += ( InputCount - 1 ) * 2;
00809
00810 LookaheadCount = FT_NEXT_USHORT( p );
00811
00812 OTV_TRACE(( " (LookaheadCount = %d)\n", LookaheadCount ));
00813
00814 OTV_LIMIT_CHECK( LookaheadCount * 2 + 2 );
00815 p += LookaheadCount * 2;
00816
00817 Count = FT_NEXT_USHORT( p );
00818
00819 OTV_TRACE(( " (Count = %d)\n", Count ));
00820
00821 OTV_LIMIT_CHECK( Count * 4 );
00822
00823 for ( ; Count > 0; Count-- )
00824 {
00825 if ( FT_NEXT_USHORT( p ) >= InputCount )
00826 FT_INVALID_DATA;
00827
00828 if ( FT_NEXT_USHORT( p ) >= valid->extra1 )
00829 FT_INVALID_DATA;
00830 }
00831
00832 OTV_EXIT;
00833 }
00834
00835
00836
00837
00838 FT_LOCAL_DEF( void )
00839 otv_u_O_O_x_Onx( FT_Bytes table,
00840 OTV_Validator valid )
00841 {
00842 FT_Bytes p = table;
00843 FT_UInt Coverage, ClassDef, ClassSetCount;
00844 OTV_Validate_Func func;
00845
00846
00847 OTV_ENTER;
00848
00849 p += 2;
00850
00851 OTV_LIMIT_CHECK( 6 );
00852 Coverage = FT_NEXT_USHORT( p );
00853 ClassDef = FT_NEXT_USHORT( p );
00854 ClassSetCount = FT_NEXT_USHORT( p );
00855
00856 OTV_TRACE(( " (ClassSetCount = %d)\n", ClassSetCount ));
00857
00858 otv_Coverage_validate( table + Coverage, valid, -1 );
00859 otv_ClassDef_validate( table + ClassDef, valid );
00860
00861 OTV_LIMIT_CHECK( ClassSetCount * 2 );
00862
00863 valid->nesting_level++;
00864 func = valid->func[valid->nesting_level];
00865 valid->extra1 = valid->lookup_count;
00866
00867 for ( ; ClassSetCount > 0; ClassSetCount-- )
00868 {
00869 FT_UInt offset = FT_NEXT_USHORT( p );
00870
00871
00872 if ( offset )
00873 func( table + offset, valid );
00874 }
00875
00876 valid->nesting_level--;
00877
00878 OTV_EXIT;
00879 }
00880
00881
00882
00883
00884 FT_LOCAL_DEF( void )
00885 otv_u_x_y_Ox_sy( FT_Bytes table,
00886 OTV_Validator valid )
00887 {
00888 FT_Bytes p = table;
00889 FT_UInt GlyphCount, Count, count1;
00890
00891
00892 OTV_ENTER;
00893
00894 p += 2;
00895
00896 OTV_LIMIT_CHECK( 4 );
00897 GlyphCount = FT_NEXT_USHORT( p );
00898 Count = FT_NEXT_USHORT( p );
00899
00900 OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount ));
00901 OTV_TRACE(( " (Count = %d)\n", Count ));
00902
00903 OTV_LIMIT_CHECK( GlyphCount * 2 + Count * 4 );
00904
00905 for ( count1 = GlyphCount; count1 > 0; count1-- )
00906 otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 );
00907
00908 for ( ; Count > 0; Count-- )
00909 {
00910 if ( FT_NEXT_USHORT( p ) >= GlyphCount )
00911 FT_INVALID_DATA;
00912
00913 if ( FT_NEXT_USHORT( p ) >= valid->lookup_count )
00914 FT_INVALID_DATA;
00915 }
00916
00917 OTV_EXIT;
00918 }
00919
00920
00921
00922
00923 FT_LOCAL_DEF( void )
00924 otv_u_O_O_O_O_x_Onx( FT_Bytes table,
00925 OTV_Validator valid )
00926 {
00927 FT_Bytes p = table;
00928 FT_UInt Coverage;
00929 FT_UInt BacktrackClassDef, InputClassDef, LookaheadClassDef;
00930 FT_UInt ChainClassSetCount;
00931 OTV_Validate_Func func;
00932
00933
00934 OTV_ENTER;
00935
00936 p += 2;
00937
00938 OTV_LIMIT_CHECK( 10 );
00939 Coverage = FT_NEXT_USHORT( p );
00940 BacktrackClassDef = FT_NEXT_USHORT( p );
00941 InputClassDef = FT_NEXT_USHORT( p );
00942 LookaheadClassDef = FT_NEXT_USHORT( p );
00943 ChainClassSetCount = FT_NEXT_USHORT( p );
00944
00945 OTV_TRACE(( " (ChainClassSetCount = %d)\n", ChainClassSetCount ));
00946
00947 otv_Coverage_validate( table + Coverage, valid, -1 );
00948
00949 otv_ClassDef_validate( table + BacktrackClassDef, valid );
00950 otv_ClassDef_validate( table + InputClassDef, valid );
00951 otv_ClassDef_validate( table + LookaheadClassDef, valid );
00952
00953 OTV_LIMIT_CHECK( ChainClassSetCount * 2 );
00954
00955 valid->nesting_level++;
00956 func = valid->func[valid->nesting_level];
00957 valid->extra1 = valid->lookup_count;
00958
00959 for ( ; ChainClassSetCount > 0; ChainClassSetCount-- )
00960 {
00961 FT_UInt offset = FT_NEXT_USHORT( p );
00962
00963
00964 if ( offset )
00965 func( table + offset, valid );
00966 }
00967
00968 valid->nesting_level--;
00969
00970 OTV_EXIT;
00971 }
00972
00973
00974
00975
00976 FT_LOCAL_DEF( void )
00977 otv_u_x_Ox_y_Oy_z_Oz_p_sp( FT_Bytes table,
00978 OTV_Validator valid )
00979 {
00980 FT_Bytes p = table;
00981 FT_UInt BacktrackGlyphCount, InputGlyphCount, LookaheadGlyphCount;
00982 FT_UInt count1, count2;
00983
00984
00985 OTV_ENTER;
00986
00987 p += 2;
00988
00989 OTV_LIMIT_CHECK( 2 );
00990 BacktrackGlyphCount = FT_NEXT_USHORT( p );
00991
00992 OTV_TRACE(( " (BacktrackGlyphCount = %d)\n", BacktrackGlyphCount ));
00993
00994 OTV_LIMIT_CHECK( BacktrackGlyphCount * 2 + 2 );
00995
00996 for ( ; BacktrackGlyphCount > 0; BacktrackGlyphCount-- )
00997 otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 );
00998
00999 InputGlyphCount = FT_NEXT_USHORT( p );
01000
01001 OTV_TRACE(( " (InputGlyphCount = %d)\n", InputGlyphCount ));
01002
01003 OTV_LIMIT_CHECK( InputGlyphCount * 2 + 2 );
01004
01005 for ( count1 = InputGlyphCount; count1 > 0; count1-- )
01006 otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 );
01007
01008 LookaheadGlyphCount = FT_NEXT_USHORT( p );
01009
01010 OTV_TRACE(( " (LookaheadGlyphCount = %d)\n", LookaheadGlyphCount ));
01011
01012 OTV_LIMIT_CHECK( LookaheadGlyphCount * 2 + 2 );
01013
01014 for ( ; LookaheadGlyphCount > 0; LookaheadGlyphCount-- )
01015 otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 );
01016
01017 count2 = FT_NEXT_USHORT( p );
01018
01019 OTV_TRACE(( " (Count = %d)\n", count2 ));
01020
01021 OTV_LIMIT_CHECK( count2 * 4 );
01022
01023 for ( ; count2 > 0; count2-- )
01024 {
01025 if ( FT_NEXT_USHORT( p ) >= InputGlyphCount )
01026 FT_INVALID_DATA;
01027
01028 if ( FT_NEXT_USHORT( p ) >= valid->lookup_count )
01029 FT_INVALID_DATA;
01030 }
01031
01032 OTV_EXIT;
01033 }
01034
01035
01036 FT_LOCAL_DEF( FT_UInt )
01037 otv_GSUBGPOS_get_Lookup_count( FT_Bytes table )
01038 {
01039 FT_Bytes p = table + 8;
01040
01041
01042 return otv_LookupList_get_count( table + FT_NEXT_USHORT( p ) );
01043 }
01044
01045
01046 FT_LOCAL_DEF( FT_UInt )
01047 otv_GSUBGPOS_have_MarkAttachmentType_flag( FT_Bytes table )
01048 {
01049 FT_Bytes p, lookup;
01050 FT_UInt count;
01051
01052
01053 if ( !table )
01054 return 0;
01055
01056
01057 p = table + 8;
01058 table += FT_NEXT_USHORT( p );
01059
01060
01061 p = table;
01062 count = FT_NEXT_USHORT( p );
01063
01064 for ( ; count > 0; count-- )
01065 {
01066 FT_Bytes oldp;
01067
01068
01069
01070 lookup = table + FT_NEXT_USHORT( p );
01071
01072 oldp = p;
01073
01074
01075 p = lookup + 2;
01076 if ( FT_NEXT_USHORT( p ) & 0xFF00U )
01077 return 1;
01078
01079 p = oldp;
01080 }
01081
01082 return 0;
01083 }
01084
01085
01086