1 /***************************************************************************/ 2 /* */ 3 /* otvcommn.c */ 4 /* */ 5 /* OpenType common tables validation (body). */ 6 /* */ 7 /* Copyright 2004-2015 by */ 8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9 /* */ 10 /* This file is part of the FreeType project, and may only be used, */ 11 /* modified, and distributed under the terms of the FreeType project */ 12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 13 /* this file you indicate that you have read the license and */ 14 /* understand and accept it fully. */ 15 /* */ 16 /***************************************************************************/ 17 18 19 #include "otvcommn.h" 20 21 22 /*************************************************************************/ 23 /* */ 24 /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 25 /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 26 /* messages during execution. */ 27 /* */ 28 #undef FT_COMPONENT 29 #define FT_COMPONENT trace_otvcommon 30 31 32 /*************************************************************************/ 33 /*************************************************************************/ 34 /***** *****/ 35 /***** COVERAGE TABLE *****/ 36 /***** *****/ 37 /*************************************************************************/ 38 /*************************************************************************/ 39 40 FT_LOCAL_DEF( void ) otv_Coverage_validate(FT_Bytes table,OTV_Validator otvalid,FT_Int expected_count)41 otv_Coverage_validate( FT_Bytes table, 42 OTV_Validator otvalid, 43 FT_Int expected_count ) 44 { 45 FT_Bytes p = table; 46 FT_UInt CoverageFormat; 47 FT_UInt total = 0; 48 49 50 OTV_NAME_ENTER( "Coverage" ); 51 52 OTV_LIMIT_CHECK( 4 ); 53 CoverageFormat = FT_NEXT_USHORT( p ); 54 55 OTV_TRACE(( " (format %d)\n", CoverageFormat )); 56 57 switch ( CoverageFormat ) 58 { 59 case 1: /* CoverageFormat1 */ 60 { 61 FT_UInt GlyphCount; 62 FT_UInt i; 63 64 65 GlyphCount = FT_NEXT_USHORT( p ); 66 67 OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); 68 69 OTV_LIMIT_CHECK( GlyphCount * 2 ); /* GlyphArray */ 70 71 for ( i = 0; i < GlyphCount; ++i ) 72 { 73 FT_UInt gid; 74 75 76 gid = FT_NEXT_USHORT( p ); 77 if ( gid >= otvalid->glyph_count ) 78 FT_INVALID_GLYPH_ID; 79 } 80 81 total = GlyphCount; 82 } 83 break; 84 85 case 2: /* CoverageFormat2 */ 86 { 87 FT_UInt n, RangeCount; 88 FT_UInt Start, End, StartCoverageIndex, last = 0; 89 90 91 RangeCount = FT_NEXT_USHORT( p ); 92 93 OTV_TRACE(( " (RangeCount = %d)\n", RangeCount )); 94 95 OTV_LIMIT_CHECK( RangeCount * 6 ); 96 97 /* RangeRecord */ 98 for ( n = 0; n < RangeCount; n++ ) 99 { 100 Start = FT_NEXT_USHORT( p ); 101 End = FT_NEXT_USHORT( p ); 102 StartCoverageIndex = FT_NEXT_USHORT( p ); 103 104 if ( Start > End || StartCoverageIndex != total ) 105 FT_INVALID_DATA; 106 107 if ( End >= otvalid->glyph_count ) 108 FT_INVALID_GLYPH_ID; 109 110 if ( n > 0 && Start <= last ) 111 FT_INVALID_DATA; 112 113 total += End - Start + 1; 114 last = End; 115 } 116 } 117 break; 118 119 default: 120 FT_INVALID_FORMAT; 121 } 122 123 /* Generally, a coverage table offset has an associated count field. */ 124 /* The number of glyphs in the table should match this field. If */ 125 /* there is no associated count, a value of -1 tells us not to check. */ 126 if ( expected_count != -1 && (FT_UInt)expected_count != total ) 127 FT_INVALID_DATA; 128 129 OTV_EXIT; 130 } 131 132 133 FT_LOCAL_DEF( FT_UInt ) otv_Coverage_get_first(FT_Bytes table)134 otv_Coverage_get_first( FT_Bytes table ) 135 { 136 FT_Bytes p = table; 137 138 139 p += 4; /* skip CoverageFormat and Glyph/RangeCount */ 140 141 return FT_NEXT_USHORT( p ); 142 } 143 144 145 FT_LOCAL_DEF( FT_UInt ) otv_Coverage_get_last(FT_Bytes table)146 otv_Coverage_get_last( FT_Bytes table ) 147 { 148 FT_Bytes p = table; 149 FT_UInt CoverageFormat = FT_NEXT_USHORT( p ); 150 FT_UInt count = FT_NEXT_USHORT( p ); /* Glyph/RangeCount */ 151 FT_UInt result = 0; 152 153 154 switch ( CoverageFormat ) 155 { 156 case 1: 157 p += ( count - 1 ) * 2; 158 result = FT_NEXT_USHORT( p ); 159 break; 160 161 case 2: 162 p += ( count - 1 ) * 6 + 2; 163 result = FT_NEXT_USHORT( p ); 164 break; 165 166 default: 167 ; 168 } 169 170 return result; 171 } 172 173 174 FT_LOCAL_DEF( FT_UInt ) otv_Coverage_get_count(FT_Bytes table)175 otv_Coverage_get_count( FT_Bytes table ) 176 { 177 FT_Bytes p = table; 178 FT_UInt CoverageFormat = FT_NEXT_USHORT( p ); 179 FT_UInt count = FT_NEXT_USHORT( p ); /* Glyph/RangeCount */ 180 FT_UInt result = 0; 181 182 183 switch ( CoverageFormat ) 184 { 185 case 1: 186 return count; 187 188 case 2: 189 { 190 FT_UInt Start, End; 191 192 193 for ( ; count > 0; count-- ) 194 { 195 Start = FT_NEXT_USHORT( p ); 196 End = FT_NEXT_USHORT( p ); 197 p += 2; /* skip StartCoverageIndex */ 198 199 result += End - Start + 1; 200 } 201 } 202 break; 203 204 default: 205 ; 206 } 207 208 return result; 209 } 210 211 212 /*************************************************************************/ 213 /*************************************************************************/ 214 /***** *****/ 215 /***** CLASS DEFINITION TABLE *****/ 216 /***** *****/ 217 /*************************************************************************/ 218 /*************************************************************************/ 219 220 FT_LOCAL_DEF( void ) otv_ClassDef_validate(FT_Bytes table,OTV_Validator otvalid)221 otv_ClassDef_validate( FT_Bytes table, 222 OTV_Validator otvalid ) 223 { 224 FT_Bytes p = table; 225 FT_UInt ClassFormat; 226 227 228 OTV_NAME_ENTER( "ClassDef" ); 229 230 OTV_LIMIT_CHECK( 4 ); 231 ClassFormat = FT_NEXT_USHORT( p ); 232 233 OTV_TRACE(( " (format %d)\n", ClassFormat )); 234 235 switch ( ClassFormat ) 236 { 237 case 1: /* ClassDefFormat1 */ 238 { 239 FT_UInt StartGlyph; 240 FT_UInt GlyphCount; 241 242 243 OTV_LIMIT_CHECK( 4 ); 244 245 StartGlyph = FT_NEXT_USHORT( p ); 246 GlyphCount = FT_NEXT_USHORT( p ); 247 248 OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); 249 250 OTV_LIMIT_CHECK( GlyphCount * 2 ); /* ClassValueArray */ 251 252 if ( StartGlyph + GlyphCount - 1 >= otvalid->glyph_count ) 253 FT_INVALID_GLYPH_ID; 254 } 255 break; 256 257 case 2: /* ClassDefFormat2 */ 258 { 259 FT_UInt n, ClassRangeCount; 260 FT_UInt Start, End, last = 0; 261 262 263 ClassRangeCount = FT_NEXT_USHORT( p ); 264 265 OTV_TRACE(( " (ClassRangeCount = %d)\n", ClassRangeCount )); 266 267 OTV_LIMIT_CHECK( ClassRangeCount * 6 ); 268 269 /* ClassRangeRecord */ 270 for ( n = 0; n < ClassRangeCount; n++ ) 271 { 272 Start = FT_NEXT_USHORT( p ); 273 End = FT_NEXT_USHORT( p ); 274 p += 2; /* skip Class */ 275 276 if ( Start > End || ( n > 0 && Start <= last ) ) 277 FT_INVALID_DATA; 278 279 if ( End >= otvalid->glyph_count ) 280 FT_INVALID_GLYPH_ID; 281 282 last = End; 283 } 284 } 285 break; 286 287 default: 288 FT_INVALID_FORMAT; 289 } 290 291 /* no need to check glyph indices used as input to class definition */ 292 /* tables since even invalid glyph indices return a meaningful result */ 293 294 OTV_EXIT; 295 } 296 297 298 /*************************************************************************/ 299 /*************************************************************************/ 300 /***** *****/ 301 /***** DEVICE TABLE *****/ 302 /***** *****/ 303 /*************************************************************************/ 304 /*************************************************************************/ 305 306 FT_LOCAL_DEF( void ) otv_Device_validate(FT_Bytes table,OTV_Validator otvalid)307 otv_Device_validate( FT_Bytes table, 308 OTV_Validator otvalid ) 309 { 310 FT_Bytes p = table; 311 FT_UInt StartSize, EndSize, DeltaFormat, count; 312 313 314 OTV_NAME_ENTER( "Device" ); 315 316 OTV_LIMIT_CHECK( 8 ); 317 StartSize = FT_NEXT_USHORT( p ); 318 EndSize = FT_NEXT_USHORT( p ); 319 DeltaFormat = FT_NEXT_USHORT( p ); 320 321 if ( DeltaFormat < 1 || DeltaFormat > 3 ) 322 FT_INVALID_FORMAT; 323 324 if ( EndSize < StartSize ) 325 FT_INVALID_DATA; 326 327 count = EndSize - StartSize + 1; 328 OTV_LIMIT_CHECK( ( 1 << DeltaFormat ) * count / 8 ); /* DeltaValue */ 329 330 OTV_EXIT; 331 } 332 333 334 /*************************************************************************/ 335 /*************************************************************************/ 336 /***** *****/ 337 /***** LOOKUPS *****/ 338 /***** *****/ 339 /*************************************************************************/ 340 /*************************************************************************/ 341 342 /* uses otvalid->type_count */ 343 /* uses otvalid->type_funcs */ 344 345 FT_LOCAL_DEF( void ) otv_Lookup_validate(FT_Bytes table,OTV_Validator otvalid)346 otv_Lookup_validate( FT_Bytes table, 347 OTV_Validator otvalid ) 348 { 349 FT_Bytes p = table; 350 FT_UInt LookupType, SubTableCount; 351 OTV_Validate_Func validate; 352 353 354 OTV_NAME_ENTER( "Lookup" ); 355 356 OTV_LIMIT_CHECK( 6 ); 357 LookupType = FT_NEXT_USHORT( p ); 358 p += 2; /* skip LookupFlag */ 359 SubTableCount = FT_NEXT_USHORT( p ); 360 361 OTV_TRACE(( " (type %d)\n", LookupType )); 362 363 if ( LookupType == 0 || LookupType > otvalid->type_count ) 364 FT_INVALID_DATA; 365 366 validate = otvalid->type_funcs[LookupType - 1]; 367 368 OTV_TRACE(( " (SubTableCount = %d)\n", SubTableCount )); 369 370 OTV_LIMIT_CHECK( SubTableCount * 2 ); 371 372 /* SubTable */ 373 for ( ; SubTableCount > 0; SubTableCount-- ) 374 validate( table + FT_NEXT_USHORT( p ), otvalid ); 375 376 OTV_EXIT; 377 } 378 379 380 /* uses valid->lookup_count */ 381 382 FT_LOCAL_DEF( void ) otv_LookupList_validate(FT_Bytes table,OTV_Validator otvalid)383 otv_LookupList_validate( FT_Bytes table, 384 OTV_Validator otvalid ) 385 { 386 FT_Bytes p = table; 387 FT_UInt LookupCount; 388 389 390 OTV_NAME_ENTER( "LookupList" ); 391 392 OTV_LIMIT_CHECK( 2 ); 393 LookupCount = FT_NEXT_USHORT( p ); 394 395 OTV_TRACE(( " (LookupCount = %d)\n", LookupCount )); 396 397 OTV_LIMIT_CHECK( LookupCount * 2 ); 398 399 otvalid->lookup_count = LookupCount; 400 401 /* Lookup */ 402 for ( ; LookupCount > 0; LookupCount-- ) 403 otv_Lookup_validate( table + FT_NEXT_USHORT( p ), otvalid ); 404 405 OTV_EXIT; 406 } 407 408 409 static FT_UInt otv_LookupList_get_count(FT_Bytes table)410 otv_LookupList_get_count( FT_Bytes table ) 411 { 412 return FT_NEXT_USHORT( table ); 413 } 414 415 416 /*************************************************************************/ 417 /*************************************************************************/ 418 /***** *****/ 419 /***** FEATURES *****/ 420 /***** *****/ 421 /*************************************************************************/ 422 /*************************************************************************/ 423 424 /* uses otvalid->lookup_count */ 425 426 FT_LOCAL_DEF( void ) otv_Feature_validate(FT_Bytes table,OTV_Validator otvalid)427 otv_Feature_validate( FT_Bytes table, 428 OTV_Validator otvalid ) 429 { 430 FT_Bytes p = table; 431 FT_UInt LookupCount; 432 433 434 OTV_NAME_ENTER( "Feature" ); 435 436 OTV_LIMIT_CHECK( 4 ); 437 p += 2; /* skip FeatureParams (unused) */ 438 LookupCount = FT_NEXT_USHORT( p ); 439 440 OTV_TRACE(( " (LookupCount = %d)\n", LookupCount )); 441 442 OTV_LIMIT_CHECK( LookupCount * 2 ); 443 444 /* LookupListIndex */ 445 for ( ; LookupCount > 0; LookupCount-- ) 446 if ( FT_NEXT_USHORT( p ) >= otvalid->lookup_count ) 447 FT_INVALID_DATA; 448 449 OTV_EXIT; 450 } 451 452 453 static FT_UInt otv_Feature_get_count(FT_Bytes table)454 otv_Feature_get_count( FT_Bytes table ) 455 { 456 return FT_NEXT_USHORT( table ); 457 } 458 459 460 /* sets otvalid->lookup_count */ 461 462 FT_LOCAL_DEF( void ) otv_FeatureList_validate(FT_Bytes table,FT_Bytes lookups,OTV_Validator otvalid)463 otv_FeatureList_validate( FT_Bytes table, 464 FT_Bytes lookups, 465 OTV_Validator otvalid ) 466 { 467 FT_Bytes p = table; 468 FT_UInt FeatureCount; 469 470 471 OTV_NAME_ENTER( "FeatureList" ); 472 473 OTV_LIMIT_CHECK( 2 ); 474 FeatureCount = FT_NEXT_USHORT( p ); 475 476 OTV_TRACE(( " (FeatureCount = %d)\n", FeatureCount )); 477 478 OTV_LIMIT_CHECK( FeatureCount * 2 ); 479 480 otvalid->lookup_count = otv_LookupList_get_count( lookups ); 481 482 /* FeatureRecord */ 483 for ( ; FeatureCount > 0; FeatureCount-- ) 484 { 485 p += 4; /* skip FeatureTag */ 486 487 /* Feature */ 488 otv_Feature_validate( table + FT_NEXT_USHORT( p ), otvalid ); 489 } 490 491 OTV_EXIT; 492 } 493 494 495 /*************************************************************************/ 496 /*************************************************************************/ 497 /***** *****/ 498 /***** LANGUAGE SYSTEM *****/ 499 /***** *****/ 500 /*************************************************************************/ 501 /*************************************************************************/ 502 503 504 /* uses otvalid->extra1 (number of features) */ 505 506 FT_LOCAL_DEF( void ) otv_LangSys_validate(FT_Bytes table,OTV_Validator otvalid)507 otv_LangSys_validate( FT_Bytes table, 508 OTV_Validator otvalid ) 509 { 510 FT_Bytes p = table; 511 FT_UInt ReqFeatureIndex; 512 FT_UInt FeatureCount; 513 514 515 OTV_NAME_ENTER( "LangSys" ); 516 517 OTV_LIMIT_CHECK( 6 ); 518 p += 2; /* skip LookupOrder (unused) */ 519 ReqFeatureIndex = FT_NEXT_USHORT( p ); 520 FeatureCount = FT_NEXT_USHORT( p ); 521 522 OTV_TRACE(( " (ReqFeatureIndex = %d)\n", ReqFeatureIndex )); 523 OTV_TRACE(( " (FeatureCount = %d)\n", FeatureCount )); 524 525 if ( ReqFeatureIndex != 0xFFFFU && ReqFeatureIndex >= otvalid->extra1 ) 526 FT_INVALID_DATA; 527 528 OTV_LIMIT_CHECK( FeatureCount * 2 ); 529 530 /* FeatureIndex */ 531 for ( ; FeatureCount > 0; FeatureCount-- ) 532 if ( FT_NEXT_USHORT( p ) >= otvalid->extra1 ) 533 FT_INVALID_DATA; 534 535 OTV_EXIT; 536 } 537 538 539 /*************************************************************************/ 540 /*************************************************************************/ 541 /***** *****/ 542 /***** SCRIPTS *****/ 543 /***** *****/ 544 /*************************************************************************/ 545 /*************************************************************************/ 546 547 FT_LOCAL_DEF( void ) otv_Script_validate(FT_Bytes table,OTV_Validator otvalid)548 otv_Script_validate( FT_Bytes table, 549 OTV_Validator otvalid ) 550 { 551 FT_UInt DefaultLangSys, LangSysCount; 552 FT_Bytes p = table; 553 554 555 OTV_NAME_ENTER( "Script" ); 556 557 OTV_LIMIT_CHECK( 4 ); 558 DefaultLangSys = FT_NEXT_USHORT( p ); 559 LangSysCount = FT_NEXT_USHORT( p ); 560 561 OTV_TRACE(( " (LangSysCount = %d)\n", LangSysCount )); 562 563 if ( DefaultLangSys != 0 ) 564 otv_LangSys_validate( table + DefaultLangSys, otvalid ); 565 566 OTV_LIMIT_CHECK( LangSysCount * 6 ); 567 568 /* LangSysRecord */ 569 for ( ; LangSysCount > 0; LangSysCount-- ) 570 { 571 p += 4; /* skip LangSysTag */ 572 573 /* LangSys */ 574 otv_LangSys_validate( table + FT_NEXT_USHORT( p ), otvalid ); 575 } 576 577 OTV_EXIT; 578 } 579 580 581 /* sets otvalid->extra1 (number of features) */ 582 583 FT_LOCAL_DEF( void ) otv_ScriptList_validate(FT_Bytes table,FT_Bytes features,OTV_Validator otvalid)584 otv_ScriptList_validate( FT_Bytes table, 585 FT_Bytes features, 586 OTV_Validator otvalid ) 587 { 588 FT_UInt ScriptCount; 589 FT_Bytes p = table; 590 591 592 OTV_NAME_ENTER( "ScriptList" ); 593 594 OTV_LIMIT_CHECK( 2 ); 595 ScriptCount = FT_NEXT_USHORT( p ); 596 597 OTV_TRACE(( " (ScriptCount = %d)\n", ScriptCount )); 598 599 OTV_LIMIT_CHECK( ScriptCount * 6 ); 600 601 otvalid->extra1 = otv_Feature_get_count( features ); 602 603 /* ScriptRecord */ 604 for ( ; ScriptCount > 0; ScriptCount-- ) 605 { 606 p += 4; /* skip ScriptTag */ 607 608 otv_Script_validate( table + FT_NEXT_USHORT( p ), otvalid ); /* Script */ 609 } 610 611 OTV_EXIT; 612 } 613 614 615 /*************************************************************************/ 616 /*************************************************************************/ 617 /***** *****/ 618 /***** UTILITY FUNCTIONS *****/ 619 /***** *****/ 620 /*************************************************************************/ 621 /*************************************************************************/ 622 623 /* 624 u: uint16 625 ux: unit16 [x] 626 627 s: struct 628 sx: struct [x] 629 sxy: struct [x], using external y count 630 631 x: uint16 x 632 633 C: Coverage 634 635 O: Offset 636 On: Offset (NULL) 637 Ox: Offset [x] 638 Onx: Offset (NULL) [x] 639 */ 640 641 FT_LOCAL_DEF( void ) otv_x_Ox(FT_Bytes table,OTV_Validator otvalid)642 otv_x_Ox( FT_Bytes table, 643 OTV_Validator otvalid ) 644 { 645 FT_Bytes p = table; 646 FT_UInt Count; 647 OTV_Validate_Func func; 648 649 650 OTV_ENTER; 651 652 OTV_LIMIT_CHECK( 2 ); 653 Count = FT_NEXT_USHORT( p ); 654 655 OTV_TRACE(( " (Count = %d)\n", Count )); 656 657 OTV_LIMIT_CHECK( Count * 2 ); 658 659 otvalid->nesting_level++; 660 func = otvalid->func[otvalid->nesting_level]; 661 662 for ( ; Count > 0; Count-- ) 663 func( table + FT_NEXT_USHORT( p ), otvalid ); 664 665 otvalid->nesting_level--; 666 667 OTV_EXIT; 668 } 669 670 671 FT_LOCAL_DEF( void ) otv_u_C_x_Ox(FT_Bytes table,OTV_Validator otvalid)672 otv_u_C_x_Ox( FT_Bytes table, 673 OTV_Validator otvalid ) 674 { 675 FT_Bytes p = table; 676 FT_UInt Count, Coverage; 677 OTV_Validate_Func func; 678 679 680 OTV_ENTER; 681 682 p += 2; /* skip Format */ 683 684 OTV_LIMIT_CHECK( 4 ); 685 Coverage = FT_NEXT_USHORT( p ); 686 Count = FT_NEXT_USHORT( p ); 687 688 OTV_TRACE(( " (Count = %d)\n", Count )); 689 690 otv_Coverage_validate( table + Coverage, otvalid, (FT_Int)Count ); 691 692 OTV_LIMIT_CHECK( Count * 2 ); 693 694 otvalid->nesting_level++; 695 func = otvalid->func[otvalid->nesting_level]; 696 697 for ( ; Count > 0; Count-- ) 698 func( table + FT_NEXT_USHORT( p ), otvalid ); 699 700 otvalid->nesting_level--; 701 702 OTV_EXIT; 703 } 704 705 706 /* uses otvalid->extra1 (if > 0: array value limit) */ 707 708 FT_LOCAL_DEF( void ) otv_x_ux(FT_Bytes table,OTV_Validator otvalid)709 otv_x_ux( FT_Bytes table, 710 OTV_Validator otvalid ) 711 { 712 FT_Bytes p = table; 713 FT_UInt Count; 714 715 716 OTV_ENTER; 717 718 OTV_LIMIT_CHECK( 2 ); 719 Count = FT_NEXT_USHORT( p ); 720 721 OTV_TRACE(( " (Count = %d)\n", Count )); 722 723 OTV_LIMIT_CHECK( Count * 2 ); 724 725 if ( otvalid->extra1 ) 726 { 727 for ( ; Count > 0; Count-- ) 728 if ( FT_NEXT_USHORT( p ) >= otvalid->extra1 ) 729 FT_INVALID_DATA; 730 } 731 732 OTV_EXIT; 733 } 734 735 736 /* `ux' in the function's name is not really correct since only x-1 */ 737 /* elements are tested */ 738 739 /* uses otvalid->extra1 (array value limit) */ 740 741 FT_LOCAL_DEF( void ) otv_x_y_ux_sy(FT_Bytes table,OTV_Validator otvalid)742 otv_x_y_ux_sy( FT_Bytes table, 743 OTV_Validator otvalid ) 744 { 745 FT_Bytes p = table; 746 FT_UInt Count1, Count2; 747 748 749 OTV_ENTER; 750 751 OTV_LIMIT_CHECK( 4 ); 752 Count1 = FT_NEXT_USHORT( p ); 753 Count2 = FT_NEXT_USHORT( p ); 754 755 OTV_TRACE(( " (Count1 = %d)\n", Count1 )); 756 OTV_TRACE(( " (Count2 = %d)\n", Count2 )); 757 758 if ( Count1 == 0 ) 759 FT_INVALID_DATA; 760 761 OTV_LIMIT_CHECK( ( Count1 - 1 ) * 2 + Count2 * 4 ); 762 p += ( Count1 - 1 ) * 2; 763 764 for ( ; Count2 > 0; Count2-- ) 765 { 766 if ( FT_NEXT_USHORT( p ) >= Count1 ) 767 FT_INVALID_DATA; 768 769 if ( FT_NEXT_USHORT( p ) >= otvalid->extra1 ) 770 FT_INVALID_DATA; 771 } 772 773 OTV_EXIT; 774 } 775 776 777 /* `uy' in the function's name is not really correct since only y-1 */ 778 /* elements are tested */ 779 780 /* uses otvalid->extra1 (array value limit) */ 781 782 FT_LOCAL_DEF( void ) otv_x_ux_y_uy_z_uz_p_sp(FT_Bytes table,OTV_Validator otvalid)783 otv_x_ux_y_uy_z_uz_p_sp( FT_Bytes table, 784 OTV_Validator otvalid ) 785 { 786 FT_Bytes p = table; 787 FT_UInt BacktrackCount, InputCount, LookaheadCount; 788 FT_UInt Count; 789 790 791 OTV_ENTER; 792 793 OTV_LIMIT_CHECK( 2 ); 794 BacktrackCount = FT_NEXT_USHORT( p ); 795 796 OTV_TRACE(( " (BacktrackCount = %d)\n", BacktrackCount )); 797 798 OTV_LIMIT_CHECK( BacktrackCount * 2 + 2 ); 799 p += BacktrackCount * 2; 800 801 InputCount = FT_NEXT_USHORT( p ); 802 if ( InputCount == 0 ) 803 FT_INVALID_DATA; 804 805 OTV_TRACE(( " (InputCount = %d)\n", InputCount )); 806 807 OTV_LIMIT_CHECK( InputCount * 2 ); 808 p += ( InputCount - 1 ) * 2; 809 810 LookaheadCount = FT_NEXT_USHORT( p ); 811 812 OTV_TRACE(( " (LookaheadCount = %d)\n", LookaheadCount )); 813 814 OTV_LIMIT_CHECK( LookaheadCount * 2 + 2 ); 815 p += LookaheadCount * 2; 816 817 Count = FT_NEXT_USHORT( p ); 818 819 OTV_TRACE(( " (Count = %d)\n", Count )); 820 821 OTV_LIMIT_CHECK( Count * 4 ); 822 823 for ( ; Count > 0; Count-- ) 824 { 825 if ( FT_NEXT_USHORT( p ) >= InputCount ) 826 FT_INVALID_DATA; 827 828 if ( FT_NEXT_USHORT( p ) >= otvalid->extra1 ) 829 FT_INVALID_DATA; 830 } 831 832 OTV_EXIT; 833 } 834 835 836 /* sets otvalid->extra1 (valid->lookup_count) */ 837 838 FT_LOCAL_DEF( void ) otv_u_O_O_x_Onx(FT_Bytes table,OTV_Validator otvalid)839 otv_u_O_O_x_Onx( FT_Bytes table, 840 OTV_Validator otvalid ) 841 { 842 FT_Bytes p = table; 843 FT_UInt Coverage, ClassDef, ClassSetCount; 844 OTV_Validate_Func func; 845 846 847 OTV_ENTER; 848 849 p += 2; /* skip Format */ 850 851 OTV_LIMIT_CHECK( 6 ); 852 Coverage = FT_NEXT_USHORT( p ); 853 ClassDef = FT_NEXT_USHORT( p ); 854 ClassSetCount = FT_NEXT_USHORT( p ); 855 856 OTV_TRACE(( " (ClassSetCount = %d)\n", ClassSetCount )); 857 858 otv_Coverage_validate( table + Coverage, otvalid, -1 ); 859 otv_ClassDef_validate( table + ClassDef, otvalid ); 860 861 OTV_LIMIT_CHECK( ClassSetCount * 2 ); 862 863 otvalid->nesting_level++; 864 func = otvalid->func[otvalid->nesting_level]; 865 otvalid->extra1 = otvalid->lookup_count; 866 867 for ( ; ClassSetCount > 0; ClassSetCount-- ) 868 { 869 FT_UInt offset = FT_NEXT_USHORT( p ); 870 871 872 if ( offset ) 873 func( table + offset, otvalid ); 874 } 875 876 otvalid->nesting_level--; 877 878 OTV_EXIT; 879 } 880 881 882 /* uses otvalid->lookup_count */ 883 884 FT_LOCAL_DEF( void ) otv_u_x_y_Ox_sy(FT_Bytes table,OTV_Validator otvalid)885 otv_u_x_y_Ox_sy( FT_Bytes table, 886 OTV_Validator otvalid ) 887 { 888 FT_Bytes p = table; 889 FT_UInt GlyphCount, Count, count1; 890 891 892 OTV_ENTER; 893 894 p += 2; /* skip Format */ 895 896 OTV_LIMIT_CHECK( 4 ); 897 GlyphCount = FT_NEXT_USHORT( p ); 898 Count = FT_NEXT_USHORT( p ); 899 900 OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount )); 901 OTV_TRACE(( " (Count = %d)\n", Count )); 902 903 OTV_LIMIT_CHECK( GlyphCount * 2 + Count * 4 ); 904 905 for ( count1 = GlyphCount; count1 > 0; count1-- ) 906 otv_Coverage_validate( table + FT_NEXT_USHORT( p ), otvalid, -1 ); 907 908 for ( ; Count > 0; Count-- ) 909 { 910 if ( FT_NEXT_USHORT( p ) >= GlyphCount ) 911 FT_INVALID_DATA; 912 913 if ( FT_NEXT_USHORT( p ) >= otvalid->lookup_count ) 914 FT_INVALID_DATA; 915 } 916 917 OTV_EXIT; 918 } 919 920 921 /* sets otvalid->extra1 (valid->lookup_count) */ 922 923 FT_LOCAL_DEF( void ) otv_u_O_O_O_O_x_Onx(FT_Bytes table,OTV_Validator otvalid)924 otv_u_O_O_O_O_x_Onx( FT_Bytes table, 925 OTV_Validator otvalid ) 926 { 927 FT_Bytes p = table; 928 FT_UInt Coverage; 929 FT_UInt BacktrackClassDef, InputClassDef, LookaheadClassDef; 930 FT_UInt ChainClassSetCount; 931 OTV_Validate_Func func; 932 933 934 OTV_ENTER; 935 936 p += 2; /* skip Format */ 937 938 OTV_LIMIT_CHECK( 10 ); 939 Coverage = FT_NEXT_USHORT( p ); 940 BacktrackClassDef = FT_NEXT_USHORT( p ); 941 InputClassDef = FT_NEXT_USHORT( p ); 942 LookaheadClassDef = FT_NEXT_USHORT( p ); 943 ChainClassSetCount = FT_NEXT_USHORT( p ); 944 945 OTV_TRACE(( " (ChainClassSetCount = %d)\n", ChainClassSetCount )); 946 947 otv_Coverage_validate( table + Coverage, otvalid, -1 ); 948 949 otv_ClassDef_validate( table + BacktrackClassDef, otvalid ); 950 otv_ClassDef_validate( table + InputClassDef, otvalid ); 951 otv_ClassDef_validate( table + LookaheadClassDef, otvalid ); 952 953 OTV_LIMIT_CHECK( ChainClassSetCount * 2 ); 954 955 otvalid->nesting_level++; 956 func = otvalid->func[otvalid->nesting_level]; 957 otvalid->extra1 = otvalid->lookup_count; 958 959 for ( ; ChainClassSetCount > 0; ChainClassSetCount-- ) 960 { 961 FT_UInt offset = FT_NEXT_USHORT( p ); 962 963 964 if ( offset ) 965 func( table + offset, otvalid ); 966 } 967 968 otvalid->nesting_level--; 969 970 OTV_EXIT; 971 } 972 973 974 /* uses otvalid->lookup_count */ 975 976 FT_LOCAL_DEF( void ) otv_u_x_Ox_y_Oy_z_Oz_p_sp(FT_Bytes table,OTV_Validator otvalid)977 otv_u_x_Ox_y_Oy_z_Oz_p_sp( FT_Bytes table, 978 OTV_Validator otvalid ) 979 { 980 FT_Bytes p = table; 981 FT_UInt BacktrackGlyphCount, InputGlyphCount, LookaheadGlyphCount; 982 FT_UInt count1, count2; 983 984 985 OTV_ENTER; 986 987 p += 2; /* skip Format */ 988 989 OTV_LIMIT_CHECK( 2 ); 990 BacktrackGlyphCount = FT_NEXT_USHORT( p ); 991 992 OTV_TRACE(( " (BacktrackGlyphCount = %d)\n", BacktrackGlyphCount )); 993 994 OTV_LIMIT_CHECK( BacktrackGlyphCount * 2 + 2 ); 995 996 for ( ; BacktrackGlyphCount > 0; BacktrackGlyphCount-- ) 997 otv_Coverage_validate( table + FT_NEXT_USHORT( p ), otvalid, -1 ); 998 999 InputGlyphCount = FT_NEXT_USHORT( p ); 1000 1001 OTV_TRACE(( " (InputGlyphCount = %d)\n", InputGlyphCount )); 1002 1003 OTV_LIMIT_CHECK( InputGlyphCount * 2 + 2 ); 1004 1005 for ( count1 = InputGlyphCount; count1 > 0; count1-- ) 1006 otv_Coverage_validate( table + FT_NEXT_USHORT( p ), otvalid, -1 ); 1007 1008 LookaheadGlyphCount = FT_NEXT_USHORT( p ); 1009 1010 OTV_TRACE(( " (LookaheadGlyphCount = %d)\n", LookaheadGlyphCount )); 1011 1012 OTV_LIMIT_CHECK( LookaheadGlyphCount * 2 + 2 ); 1013 1014 for ( ; LookaheadGlyphCount > 0; LookaheadGlyphCount-- ) 1015 otv_Coverage_validate( table + FT_NEXT_USHORT( p ), otvalid, -1 ); 1016 1017 count2 = FT_NEXT_USHORT( p ); 1018 1019 OTV_TRACE(( " (Count = %d)\n", count2 )); 1020 1021 OTV_LIMIT_CHECK( count2 * 4 ); 1022 1023 for ( ; count2 > 0; count2-- ) 1024 { 1025 if ( FT_NEXT_USHORT( p ) >= InputGlyphCount ) 1026 FT_INVALID_DATA; 1027 1028 if ( FT_NEXT_USHORT( p ) >= otvalid->lookup_count ) 1029 FT_INVALID_DATA; 1030 } 1031 1032 OTV_EXIT; 1033 } 1034 1035 1036 FT_LOCAL_DEF( FT_UInt ) otv_GSUBGPOS_get_Lookup_count(FT_Bytes table)1037 otv_GSUBGPOS_get_Lookup_count( FT_Bytes table ) 1038 { 1039 FT_Bytes p = table + 8; 1040 1041 1042 return otv_LookupList_get_count( table + FT_NEXT_USHORT( p ) ); 1043 } 1044 1045 1046 FT_LOCAL_DEF( FT_UInt ) otv_GSUBGPOS_have_MarkAttachmentType_flag(FT_Bytes table)1047 otv_GSUBGPOS_have_MarkAttachmentType_flag( FT_Bytes table ) 1048 { 1049 FT_Bytes p, lookup; 1050 FT_UInt count; 1051 1052 1053 if ( !table ) 1054 return 0; 1055 1056 /* LookupList */ 1057 p = table + 8; 1058 table += FT_NEXT_USHORT( p ); 1059 1060 /* LookupCount */ 1061 p = table; 1062 count = FT_NEXT_USHORT( p ); 1063 1064 for ( ; count > 0; count-- ) 1065 { 1066 FT_Bytes oldp; 1067 1068 1069 /* Lookup */ 1070 lookup = table + FT_NEXT_USHORT( p ); 1071 1072 oldp = p; 1073 1074 /* LookupFlag */ 1075 p = lookup + 2; 1076 if ( FT_NEXT_USHORT( p ) & 0xFF00U ) 1077 return 1; 1078 1079 p = oldp; 1080 } 1081 1082 return 0; 1083 } 1084 1085 1086 /* END */ 1087