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