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