1 /**************************************************************************** 2 * 3 * gxvcommn.h 4 * 5 * TrueTypeGX/AAT common tables validation (specification). 6 * 7 * Copyright (C) 2004-2023 by 8 * suzuki toshiya, Masatake YAMATO, Red Hat K.K., 9 * David Turner, Robert Wilhelm, and Werner Lemberg. 10 * 11 * This file is part of the FreeType project, and may only be used, 12 * modified, and distributed under the terms of the FreeType project 13 * license, LICENSE.TXT. By continuing to use, modify, or distribute 14 * this file you indicate that you have read the license and 15 * understand and accept it fully. 16 * 17 */ 18 19 /**************************************************************************** 20 * 21 * gxvalid is derived from both gxlayout module and otvalid module. 22 * Development of gxlayout is supported by the Information-technology 23 * Promotion Agency(IPA), Japan. 24 * 25 */ 26 27 28 /* 29 * keywords in variable naming 30 * --------------------------- 31 * table: Of type FT_Bytes, pointing to the start of this table/subtable. 32 * limit: Of type FT_Bytes, pointing to the end of this table/subtable, 33 * including padding for alignment. 34 * offset: Of type FT_UInt, the number of octets from the start to target. 35 * length: Of type FT_UInt, the number of octets from the start to the 36 * end in this table/subtable, including padding for alignment. 37 * 38 * _MIN, _MAX: Should be added to the tail of macros, as INT_MIN, etc. 39 */ 40 41 42 #ifndef GXVCOMMN_H_ 43 #define GXVCOMMN_H_ 44 45 46 #include "gxvalid.h" 47 #include <freetype/internal/ftdebug.h> 48 #include <freetype/ftsnames.h> 49 50 51 FT_BEGIN_HEADER 52 53 54 /* some variables are not evaluated or only used in trace */ 55 56 #ifdef FT_DEBUG_LEVEL_TRACE 57 #define GXV_LOAD_TRACE_VARS 58 #else 59 #undef GXV_LOAD_TRACE_VARS 60 #endif 61 62 #undef GXV_LOAD_UNUSED_VARS /* debug purpose */ 63 64 #define IS_PARANOID_VALIDATION \ 65 ( gxvalid->root->level >= FT_VALIDATE_PARANOID ) 66 #define GXV_SET_ERR_IF_PARANOID( err ) \ 67 do { if ( IS_PARANOID_VALIDATION ) ( err ); } while ( 0 ) 68 69 70 /*************************************************************************/ 71 /*************************************************************************/ 72 /***** *****/ 73 /***** VALIDATION *****/ 74 /***** *****/ 75 /*************************************************************************/ 76 /*************************************************************************/ 77 78 typedef struct GXV_ValidatorRec_* GXV_Validator; 79 80 81 #define DUMMY_LIMIT 0 82 83 typedef void 84 (*GXV_Validate_Func)( FT_Bytes table, 85 FT_Bytes limit, 86 GXV_Validator gxvalid ); 87 88 89 /* ====================== LookupTable Validator ======================== */ 90 91 typedef union GXV_LookupValueDesc_ 92 { 93 FT_UShort u; 94 FT_Short s; 95 96 } GXV_LookupValueDesc; 97 98 typedef const GXV_LookupValueDesc* GXV_LookupValueCPtr; 99 100 typedef enum GXV_LookupValue_SignSpec_ 101 { 102 GXV_LOOKUPVALUE_UNSIGNED = 0, 103 GXV_LOOKUPVALUE_SIGNED 104 105 } GXV_LookupValue_SignSpec; 106 107 108 typedef void 109 (*GXV_Lookup_Value_Validate_Func)( FT_UShort glyph, 110 GXV_LookupValueCPtr value_p, 111 GXV_Validator gxvalid ); 112 113 typedef GXV_LookupValueDesc 114 (*GXV_Lookup_Fmt4_Transit_Func)( FT_UShort relative_gindex, 115 GXV_LookupValueCPtr base_value_p, 116 FT_Bytes lookuptbl_limit, 117 GXV_Validator gxvalid ); 118 119 120 /* ====================== StateTable Validator ========================= */ 121 122 typedef enum GXV_GlyphOffset_Format_ 123 { 124 GXV_GLYPHOFFSET_NONE = -1, 125 GXV_GLYPHOFFSET_UCHAR = 2, 126 GXV_GLYPHOFFSET_CHAR, 127 GXV_GLYPHOFFSET_USHORT = 4, 128 GXV_GLYPHOFFSET_SHORT, 129 GXV_GLYPHOFFSET_ULONG = 8, 130 GXV_GLYPHOFFSET_LONG 131 132 } GXV_GlyphOffset_Format; 133 134 135 #define GXV_GLYPHOFFSET_FMT( table ) \ 136 ( gxvalid->table.entry_glyphoffset_fmt ) 137 138 #define GXV_GLYPHOFFSET_SIZE( table ) \ 139 ( gxvalid->table.entry_glyphoffset_fmt / 2 ) 140 141 142 /* ----------------------- 16bit StateTable ---------------------------- */ 143 144 typedef union GXV_StateTable_GlyphOffsetDesc_ 145 { 146 FT_Byte uc; 147 FT_UShort u; /* same as GXV_LookupValueDesc */ 148 FT_ULong ul; 149 FT_Char c; 150 FT_Short s; /* same as GXV_LookupValueDesc */ 151 FT_Long l; 152 153 } GXV_StateTable_GlyphOffsetDesc; 154 155 typedef const GXV_StateTable_GlyphOffsetDesc* GXV_StateTable_GlyphOffsetCPtr; 156 157 typedef void 158 (*GXV_StateTable_Subtable_Setup_Func)( FT_UShort table_size, 159 FT_UShort classTable, 160 FT_UShort stateArray, 161 FT_UShort entryTable, 162 FT_UShort* classTable_length_p, 163 FT_UShort* stateArray_length_p, 164 FT_UShort* entryTable_length_p, 165 GXV_Validator gxvalid ); 166 167 typedef void 168 (*GXV_StateTable_Entry_Validate_Func)( 169 FT_Byte state, 170 FT_UShort flags, 171 GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, 172 FT_Bytes statetable_table, 173 FT_Bytes statetable_limit, 174 GXV_Validator gxvalid ); 175 176 typedef void 177 (*GXV_StateTable_OptData_Load_Func)( FT_Bytes table, 178 FT_Bytes limit, 179 GXV_Validator gxvalid ); 180 181 typedef struct GXV_StateTable_ValidatorRec_ 182 { 183 GXV_GlyphOffset_Format entry_glyphoffset_fmt; 184 void* optdata; 185 186 GXV_StateTable_Subtable_Setup_Func subtable_setup_func; 187 GXV_StateTable_Entry_Validate_Func entry_validate_func; 188 GXV_StateTable_OptData_Load_Func optdata_load_func; 189 190 } GXV_StateTable_ValidatorRec, *GXV_StateTable_ValidatorRecData; 191 192 193 /* ---------------------- 32bit XStateTable ---------------------------- */ 194 195 typedef GXV_StateTable_GlyphOffsetDesc GXV_XStateTable_GlyphOffsetDesc; 196 197 typedef const GXV_XStateTable_GlyphOffsetDesc* GXV_XStateTable_GlyphOffsetCPtr; 198 199 typedef void 200 (*GXV_XStateTable_Subtable_Setup_Func)( FT_ULong table_size, 201 FT_ULong classTable, 202 FT_ULong stateArray, 203 FT_ULong entryTable, 204 FT_ULong* classTable_length_p, 205 FT_ULong* stateArray_length_p, 206 FT_ULong* entryTable_length_p, 207 GXV_Validator gxvalid ); 208 209 typedef void 210 (*GXV_XStateTable_Entry_Validate_Func)( 211 FT_UShort state, 212 FT_UShort flags, 213 GXV_StateTable_GlyphOffsetCPtr glyphOffset_p, 214 FT_Bytes xstatetable_table, 215 FT_Bytes xstatetable_limit, 216 GXV_Validator gxvalid ); 217 218 219 typedef GXV_StateTable_OptData_Load_Func GXV_XStateTable_OptData_Load_Func; 220 221 222 typedef struct GXV_XStateTable_ValidatorRec_ 223 { 224 int entry_glyphoffset_fmt; 225 void* optdata; 226 227 GXV_XStateTable_Subtable_Setup_Func subtable_setup_func; 228 GXV_XStateTable_Entry_Validate_Func entry_validate_func; 229 GXV_XStateTable_OptData_Load_Func optdata_load_func; 230 231 FT_ULong nClasses; 232 FT_UShort maxClassID; 233 234 } GXV_XStateTable_ValidatorRec, *GXV_XStateTable_ValidatorRecData; 235 236 237 /* ===================================================================== */ 238 239 typedef struct GXV_ValidatorRec_ 240 { 241 FT_Validator root; 242 243 FT_Face face; 244 void* table_data; 245 246 FT_ULong subtable_length; 247 248 GXV_LookupValue_SignSpec lookupval_sign; 249 GXV_Lookup_Value_Validate_Func lookupval_func; 250 GXV_Lookup_Fmt4_Transit_Func lookupfmt4_trans; 251 FT_Bytes lookuptbl_head; 252 253 FT_UShort min_gid; 254 FT_UShort max_gid; 255 256 GXV_StateTable_ValidatorRec statetable; 257 GXV_XStateTable_ValidatorRec xstatetable; 258 259 #ifdef FT_DEBUG_LEVEL_TRACE 260 FT_UInt debug_indent; 261 const FT_String* debug_function_name[3]; 262 #endif 263 264 } GXV_ValidatorRec; 265 266 267 #define GXV_TABLE_DATA( tag, field ) \ 268 ( ( (GXV_ ## tag ## _Data)gxvalid->table_data )->field ) 269 270 #undef FT_INVALID_ 271 #define FT_INVALID_( _error ) \ 272 ft_validator_error( gxvalid->root, FT_THROW( _error ) ) 273 274 #define GXV_LIMIT_CHECK( _count ) \ 275 FT_BEGIN_STMNT \ 276 if ( p + _count > ( limit? limit : gxvalid->root->limit ) ) \ 277 FT_INVALID_TOO_SHORT; \ 278 FT_END_STMNT 279 280 281 #ifdef FT_DEBUG_LEVEL_TRACE 282 283 #define GXV_INIT gxvalid->debug_indent = 0 284 285 #define GXV_NAME_ENTER( name ) \ 286 FT_BEGIN_STMNT \ 287 gxvalid->debug_indent += 2; \ 288 FT_TRACE4(( "%*.s", gxvalid->debug_indent, "" )); \ 289 FT_TRACE4(( "%s table\n", name )); \ 290 FT_END_STMNT 291 292 #define GXV_EXIT gxvalid->debug_indent -= 2 293 294 #define GXV_TRACE( s ) \ 295 FT_BEGIN_STMNT \ 296 FT_TRACE4(( "%*.s", gxvalid->debug_indent, "" )); \ 297 FT_TRACE4( s ); \ 298 FT_END_STMNT 299 300 #else /* !FT_DEBUG_LEVEL_TRACE */ 301 302 #define GXV_INIT do { } while ( 0 ) 303 #define GXV_NAME_ENTER( name ) do { } while ( 0 ) 304 #define GXV_EXIT do { } while ( 0 ) 305 306 #define GXV_TRACE( s ) do { } while ( 0 ) 307 308 #endif /* !FT_DEBUG_LEVEL_TRACE */ 309 310 311 /*************************************************************************/ 312 /*************************************************************************/ 313 /***** *****/ 314 /***** 32bit alignment checking *****/ 315 /***** *****/ 316 /*************************************************************************/ 317 /*************************************************************************/ 318 319 #define GXV_32BIT_ALIGNMENT_VALIDATE( a ) \ 320 FT_BEGIN_STMNT \ 321 { \ 322 if ( (a) & 3 ) \ 323 FT_INVALID_OFFSET; \ 324 } \ 325 FT_END_STMNT 326 327 328 /*************************************************************************/ 329 /*************************************************************************/ 330 /***** *****/ 331 /***** Dumping Binary Data *****/ 332 /***** *****/ 333 /*************************************************************************/ 334 /*************************************************************************/ 335 336 #define GXV_TRACE_HEXDUMP( p, len ) \ 337 FT_BEGIN_STMNT \ 338 { \ 339 FT_Bytes b; \ 340 \ 341 \ 342 for ( b = p; b < (FT_Bytes)p + len; b++ ) \ 343 FT_TRACE1(("\\x%02x", *b)); \ 344 } \ 345 FT_END_STMNT 346 347 #define GXV_TRACE_HEXDUMP_C( p, len ) \ 348 FT_BEGIN_STMNT \ 349 { \ 350 FT_Bytes b; \ 351 \ 352 \ 353 for ( b = p; b < (FT_Bytes)p + len; b++ ) \ 354 if ( 0x40 < *b && *b < 0x7E ) \ 355 FT_TRACE1(("%c", *b)); \ 356 else \ 357 FT_TRACE1(("\\x%02x", *b)); \ 358 } \ 359 FT_END_STMNT 360 361 #define GXV_TRACE_HEXDUMP_SFNTNAME( n ) \ 362 GXV_TRACE_HEXDUMP( n.string, n.string_len ) 363 364 365 /*************************************************************************/ 366 /*************************************************************************/ 367 /***** *****/ 368 /***** LOOKUP TABLE *****/ 369 /***** *****/ 370 /*************************************************************************/ 371 /*************************************************************************/ 372 373 FT_LOCAL( void ) 374 gxv_BinSrchHeader_validate( FT_Bytes p, 375 FT_Bytes limit, 376 FT_UShort* unitSize_p, 377 FT_UShort* nUnits_p, 378 GXV_Validator gxvalid ); 379 380 FT_LOCAL( void ) 381 gxv_LookupTable_validate( FT_Bytes table, 382 FT_Bytes limit, 383 GXV_Validator gxvalid ); 384 385 386 /*************************************************************************/ 387 /*************************************************************************/ 388 /***** *****/ 389 /***** Glyph ID *****/ 390 /***** *****/ 391 /*************************************************************************/ 392 /*************************************************************************/ 393 394 FT_LOCAL( FT_Int ) 395 gxv_glyphid_validate( FT_UShort gid, 396 GXV_Validator gxvalid ); 397 398 399 /*************************************************************************/ 400 /*************************************************************************/ 401 /***** *****/ 402 /***** CONTROL POINT *****/ 403 /***** *****/ 404 /*************************************************************************/ 405 /*************************************************************************/ 406 407 FT_LOCAL( void ) 408 gxv_ctlPoint_validate( FT_UShort gid, 409 FT_UShort ctl_point, 410 GXV_Validator gxvalid ); 411 412 413 /*************************************************************************/ 414 /*************************************************************************/ 415 /***** *****/ 416 /***** SFNT NAME *****/ 417 /***** *****/ 418 /*************************************************************************/ 419 /*************************************************************************/ 420 421 FT_LOCAL( void ) 422 gxv_sfntName_validate( FT_UShort name_index, 423 FT_UShort min_index, 424 FT_UShort max_index, 425 GXV_Validator gxvalid ); 426 427 428 /*************************************************************************/ 429 /*************************************************************************/ 430 /***** *****/ 431 /***** STATE TABLE *****/ 432 /***** *****/ 433 /*************************************************************************/ 434 /*************************************************************************/ 435 436 FT_LOCAL( void ) 437 gxv_StateTable_subtable_setup( FT_UShort table_size, 438 FT_UShort classTable, 439 FT_UShort stateArray, 440 FT_UShort entryTable, 441 FT_UShort* classTable_length_p, 442 FT_UShort* stateArray_length_p, 443 FT_UShort* entryTable_length_p, 444 GXV_Validator gxvalid ); 445 446 FT_LOCAL( void ) 447 gxv_XStateTable_subtable_setup( FT_ULong table_size, 448 FT_ULong classTable, 449 FT_ULong stateArray, 450 FT_ULong entryTable, 451 FT_ULong* classTable_length_p, 452 FT_ULong* stateArray_length_p, 453 FT_ULong* entryTable_length_p, 454 GXV_Validator gxvalid ); 455 456 FT_LOCAL( void ) 457 gxv_StateTable_validate( FT_Bytes table, 458 FT_Bytes limit, 459 GXV_Validator gxvalid ); 460 461 FT_LOCAL( void ) 462 gxv_XStateTable_validate( FT_Bytes table, 463 FT_Bytes limit, 464 GXV_Validator gxvalid ); 465 466 467 /*************************************************************************/ 468 /*************************************************************************/ 469 /***** *****/ 470 /***** UTILITY MACROS AND FUNCTIONS *****/ 471 /***** *****/ 472 /*************************************************************************/ 473 /*************************************************************************/ 474 475 FT_LOCAL( void ) 476 gxv_array_getlimits_byte( FT_Bytes table, 477 FT_Bytes limit, 478 FT_Byte* min, 479 FT_Byte* max, 480 GXV_Validator gxvalid ); 481 482 FT_LOCAL( void ) 483 gxv_array_getlimits_ushort( FT_Bytes table, 484 FT_Bytes limit, 485 FT_UShort* min, 486 FT_UShort* max, 487 GXV_Validator gxvalid ); 488 489 FT_LOCAL( void ) 490 gxv_set_length_by_ushort_offset( FT_UShort* offset, 491 FT_UShort** length, 492 FT_UShort* buff, 493 FT_UInt nmemb, 494 FT_UShort limit, 495 GXV_Validator gxvalid ); 496 497 FT_LOCAL( void ) 498 gxv_set_length_by_ulong_offset( FT_ULong* offset, 499 FT_ULong** length, 500 FT_ULong* buff, 501 FT_UInt nmemb, 502 FT_ULong limit, 503 GXV_Validator gxvalid); 504 505 506 #define GXV_SUBTABLE_OFFSET_CHECK( _offset ) \ 507 FT_BEGIN_STMNT \ 508 if ( (_offset) > gxvalid->subtable_length ) \ 509 FT_INVALID_OFFSET; \ 510 FT_END_STMNT 511 512 #define GXV_SUBTABLE_LIMIT_CHECK( _count ) \ 513 FT_BEGIN_STMNT \ 514 if ( ( p + (_count) - gxvalid->subtable_start ) > \ 515 gxvalid->subtable_length ) \ 516 FT_INVALID_TOO_SHORT; \ 517 FT_END_STMNT 518 519 #define GXV_USHORT_TO_SHORT( _us ) \ 520 ( ( 0x8000U < ( _us ) ) ? ( ( _us ) - 0x8000U ) : ( _us ) ) 521 522 #define GXV_STATETABLE_HEADER_SIZE ( 2 + 2 + 2 + 2 ) 523 #define GXV_STATEHEADER_SIZE GXV_STATETABLE_HEADER_SIZE 524 525 #define GXV_XSTATETABLE_HEADER_SIZE ( 4 + 4 + 4 + 4 ) 526 #define GXV_XSTATEHEADER_SIZE GXV_XSTATETABLE_HEADER_SIZE 527 528 529 /*************************************************************************/ 530 /*************************************************************************/ 531 /***** *****/ 532 /***** Table overlapping *****/ 533 /***** *****/ 534 /*************************************************************************/ 535 /*************************************************************************/ 536 537 typedef struct GXV_odtect_DataRec_ 538 { 539 FT_Bytes start; 540 FT_ULong length; 541 FT_String* name; 542 543 } GXV_odtect_DataRec, *GXV_odtect_Data; 544 545 typedef struct GXV_odtect_RangeRec_ 546 { 547 FT_UInt nRanges; 548 GXV_odtect_Data range; 549 550 } GXV_odtect_RangeRec, *GXV_odtect_Range; 551 552 553 FT_LOCAL( void ) 554 gxv_odtect_add_range( FT_Bytes start, 555 FT_ULong length, 556 const FT_String* name, 557 GXV_odtect_Range odtect ); 558 559 FT_LOCAL( void ) 560 gxv_odtect_validate( GXV_odtect_Range odtect, 561 GXV_Validator gxvalid ); 562 563 564 #define GXV_ODTECT( n, odtect ) \ 565 GXV_odtect_DataRec odtect ## _range[n]; \ 566 GXV_odtect_RangeRec odtect ## _rec = { 0, NULL }; \ 567 GXV_odtect_Range odtect = NULL 568 569 #define GXV_ODTECT_INIT( odtect ) \ 570 FT_BEGIN_STMNT \ 571 odtect ## _rec.nRanges = 0; \ 572 odtect ## _rec.range = odtect ## _range; \ 573 odtect = & odtect ## _rec; \ 574 FT_END_STMNT 575 576 577 /* */ 578 579 FT_END_HEADER 580 581 #endif /* GXVCOMMN_H_ */ 582 583 584 /* END */ 585