00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "gxvalid.h"
00028 #include "gxvcommn.h"
00029
00030 #include FT_SFNT_NAMES_H
00031
00032
00033
00034
00035
00036
00037
00038
00039 #undef FT_COMPONENT
00040 #define FT_COMPONENT trace_gxvjust
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 typedef struct GXV_just_DataRec_
00056 {
00057 FT_UShort wdc_offset_max;
00058 FT_UShort wdc_offset_min;
00059 FT_UShort pc_offset_max;
00060 FT_UShort pc_offset_min;
00061
00062 } GXV_just_DataRec, *GXV_just_Data;
00063
00064
00065 #define GXV_JUST_DATA( a ) GXV_TABLE_DATA( just, a )
00066
00067
00068 static void
00069 gxv_just_wdp_entry_validate( FT_Bytes table,
00070 FT_Bytes limit,
00071 GXV_Validator valid )
00072 {
00073 FT_Bytes p = table;
00074 FT_ULong justClass;
00075 FT_Fixed beforeGrowLimit;
00076 FT_Fixed beforeShrinkGrowLimit;
00077 FT_Fixed afterGrowLimit;
00078 FT_Fixed afterShrinkGrowLimit;
00079 FT_UShort growFlags;
00080 FT_UShort shrinkFlags;
00081
00082
00083 GXV_LIMIT_CHECK( 4 + 4 + 4 + 4 + 4 + 2 + 2 );
00084 justClass = FT_NEXT_ULONG( p );
00085 beforeGrowLimit = FT_NEXT_ULONG( p );
00086 beforeShrinkGrowLimit = FT_NEXT_ULONG( p );
00087 afterGrowLimit = FT_NEXT_ULONG( p );
00088 afterShrinkGrowLimit = FT_NEXT_ULONG( p );
00089 growFlags = FT_NEXT_USHORT( p );
00090 shrinkFlags = FT_NEXT_USHORT( p );
00091
00092
00093
00094 valid->subtable_length = p - table;
00095 }
00096
00097
00098 static void
00099 gxv_just_wdc_entry_validate( FT_Bytes table,
00100 FT_Bytes limit,
00101 GXV_Validator valid )
00102 {
00103 FT_Bytes p = table;
00104 FT_ULong count, i;
00105
00106
00107 GXV_LIMIT_CHECK( 4 );
00108 count = FT_NEXT_ULONG( p );
00109 for ( i = 0; i < count; i++ )
00110 {
00111 GXV_TRACE(( "validating wdc pair %d/%d\n", i + 1, count ));
00112 gxv_just_wdp_entry_validate( p, limit, valid );
00113 p += valid->subtable_length;
00114 }
00115
00116 valid->subtable_length = p - table;
00117 }
00118
00119
00120 static void
00121 gxv_just_widthDeltaClusters_validate( FT_Bytes table,
00122 FT_Bytes limit,
00123 GXV_Validator valid )
00124 {
00125 FT_Bytes p = table ;
00126 FT_Bytes wdc_end = table + GXV_JUST_DATA( wdc_offset_max );
00127 FT_UInt i;
00128
00129
00130 GXV_NAME_ENTER( "just justDeltaClusters" );
00131
00132 if ( limit <= wdc_end )
00133 FT_INVALID_OFFSET;
00134
00135 for ( i = 0; p <= wdc_end; i++ )
00136 {
00137 gxv_just_wdc_entry_validate( p, limit, valid );
00138 p += valid->subtable_length;
00139 }
00140
00141 valid->subtable_length = p - table;
00142
00143 GXV_EXIT;
00144 }
00145
00146
00147 static void
00148 gxv_just_actSubrecord_type0_validate( FT_Bytes table,
00149 FT_Bytes limit,
00150 GXV_Validator valid )
00151 {
00152 FT_Bytes p = table;
00153
00154 FT_Fixed lowerLimit;
00155 FT_Fixed upperLimit;
00156
00157 FT_UShort order;
00158 FT_UShort decomposedCount;
00159
00160 FT_UInt i;
00161
00162
00163 GXV_LIMIT_CHECK( 4 + 4 + 2 + 2 );
00164 lowerLimit = FT_NEXT_ULONG( p );
00165 upperLimit = FT_NEXT_ULONG( p );
00166 order = FT_NEXT_USHORT( p );
00167 decomposedCount = FT_NEXT_USHORT( p );
00168
00169 for ( i = 0; i < decomposedCount; i++ )
00170 {
00171 FT_UShort glyphs;
00172
00173
00174 GXV_LIMIT_CHECK( 2 );
00175 glyphs = FT_NEXT_USHORT( p );
00176 }
00177
00178 valid->subtable_length = p - table;
00179 }
00180
00181
00182 static void
00183 gxv_just_actSubrecord_type1_validate( FT_Bytes table,
00184 FT_Bytes limit,
00185 GXV_Validator valid )
00186 {
00187 FT_Bytes p = table;
00188 FT_UShort addGlyph;
00189
00190
00191 GXV_LIMIT_CHECK( 2 );
00192 addGlyph = FT_NEXT_USHORT( p );
00193
00194 valid->subtable_length = p - table;
00195 }
00196
00197
00198 static void
00199 gxv_just_actSubrecord_type2_validate( FT_Bytes table,
00200 FT_Bytes limit,
00201 GXV_Validator valid )
00202 {
00203 FT_Bytes p = table;
00204 FT_Fixed substThreshhold;
00205 FT_UShort addGlyph;
00206 FT_UShort substGlyph;
00207
00208
00209 GXV_LIMIT_CHECK( 4 + 2 + 2 );
00210 substThreshhold = FT_NEXT_ULONG( p );
00211 addGlyph = FT_NEXT_USHORT( p );
00212 substGlyph = FT_NEXT_USHORT( p );
00213
00214 valid->subtable_length = p - table;
00215 }
00216
00217
00218 static void
00219 gxv_just_actSubrecord_type4_validate( FT_Bytes table,
00220 FT_Bytes limit,
00221 GXV_Validator valid )
00222 {
00223 FT_Bytes p = table;
00224 FT_ULong variantsAxis;
00225 FT_Fixed minimumLimit;
00226 FT_Fixed noStretchValue;
00227 FT_Fixed maximumLimit;
00228
00229
00230 GXV_LIMIT_CHECK( 4 + 4 + 4 + 4 );
00231 variantsAxis = FT_NEXT_ULONG( p );
00232 minimumLimit = FT_NEXT_ULONG( p );
00233 noStretchValue = FT_NEXT_ULONG( p );
00234 maximumLimit = FT_NEXT_ULONG( p );
00235
00236 valid->subtable_length = p - table;
00237 }
00238
00239
00240 static void
00241 gxv_just_actSubrecord_type5_validate( FT_Bytes table,
00242 FT_Bytes limit,
00243 GXV_Validator valid )
00244 {
00245 FT_Bytes p = table;
00246 FT_UShort flags;
00247 FT_UShort glyph;
00248
00249
00250 GXV_LIMIT_CHECK( 2 + 2 );
00251 flags = FT_NEXT_USHORT( p );
00252 glyph = FT_NEXT_USHORT( p );
00253
00254 valid->subtable_length = p - table;
00255 }
00256
00257
00258
00259 static void
00260 gxv_just_actSubrecord_validate( FT_Bytes table,
00261 FT_Bytes limit,
00262 GXV_Validator valid )
00263 {
00264 FT_Bytes p = table;
00265 FT_UShort actionClass;
00266 FT_UShort actionType;
00267 FT_ULong actionLength;
00268
00269
00270 GXV_NAME_ENTER( "just actSubrecord" );
00271
00272 GXV_LIMIT_CHECK( 2 + 2 + 4 );
00273 actionClass = FT_NEXT_USHORT( p );
00274 actionType = FT_NEXT_USHORT( p );
00275 actionLength = FT_NEXT_ULONG( p );
00276
00277 if ( actionType == 0 )
00278 gxv_just_actSubrecord_type0_validate( p, limit, valid );
00279 else if ( actionType == 1 )
00280 gxv_just_actSubrecord_type1_validate( p, limit, valid );
00281 else if ( actionType == 2 )
00282 gxv_just_actSubrecord_type2_validate( p, limit, valid );
00283 else if ( actionType == 3 )
00284 ;
00285 else if ( actionType == 4 )
00286 gxv_just_actSubrecord_type4_validate( p, limit, valid );
00287 else if ( actionType == 5 )
00288 gxv_just_actSubrecord_type5_validate( p, limit, valid );
00289 else
00290 FT_INVALID_DATA;
00291
00292 valid->subtable_length = actionLength;
00293
00294 GXV_EXIT;
00295 }
00296
00297
00298 static void
00299 gxv_just_pcActionRecord_validate( FT_Bytes table,
00300 FT_Bytes limit,
00301 GXV_Validator valid )
00302 {
00303 FT_Bytes p = table;
00304 FT_ULong actionCount;
00305 FT_ULong i;
00306
00307
00308 GXV_LIMIT_CHECK( 4 );
00309 actionCount = FT_NEXT_ULONG( p );
00310 GXV_TRACE(( "actionCount = %d\n", actionCount ));
00311
00312 for ( i = 0; i < actionCount; i++ )
00313 {
00314 gxv_just_actSubrecord_validate( p, limit, valid );
00315 p += valid->subtable_length;
00316 }
00317
00318 valid->subtable_length = p - table;
00319
00320 GXV_EXIT;
00321 }
00322
00323
00324 static void
00325 gxv_just_pcTable_LookupValue_entry_validate( FT_UShort glyph,
00326 GXV_LookupValueCPtr value_p,
00327 GXV_Validator valid )
00328 {
00329 FT_UNUSED( glyph );
00330
00331 if ( value_p->u > GXV_JUST_DATA( pc_offset_max ) )
00332 GXV_JUST_DATA( pc_offset_max ) = value_p->u;
00333 if ( value_p->u < GXV_JUST_DATA( pc_offset_max ) )
00334 GXV_JUST_DATA( pc_offset_min ) = value_p->u;
00335 }
00336
00337
00338 static void
00339 gxv_just_pcLookupTable_validate( FT_Bytes table,
00340 FT_Bytes limit,
00341 GXV_Validator valid )
00342 {
00343 FT_Bytes p = table;
00344
00345
00346 GXV_NAME_ENTER( "just pcLookupTable" );
00347 GXV_JUST_DATA( pc_offset_max ) = 0x0000;
00348 GXV_JUST_DATA( pc_offset_min ) = 0xFFFFU;
00349
00350 valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED;
00351 valid->lookupval_func = gxv_just_pcTable_LookupValue_entry_validate;
00352
00353 gxv_LookupTable_validate( p, limit, valid );
00354
00355
00356
00357 GXV_EXIT;
00358 }
00359
00360
00361 static void
00362 gxv_just_postcompTable_validate( FT_Bytes table,
00363 FT_Bytes limit,
00364 GXV_Validator valid )
00365 {
00366 FT_Bytes p = table;
00367
00368
00369 GXV_NAME_ENTER( "just postcompTable" );
00370
00371 gxv_just_pcLookupTable_validate( p, limit, valid );
00372 p += valid->subtable_length;
00373
00374 gxv_just_pcActionRecord_validate( p, limit, valid );
00375 p += valid->subtable_length;
00376
00377 valid->subtable_length = p - table;
00378
00379 GXV_EXIT;
00380 }
00381
00382
00383 static void
00384 gxv_just_classTable_entry_validate(
00385 FT_Byte state,
00386 FT_UShort flags,
00387 GXV_StateTable_GlyphOffsetCPtr glyphOffset_p,
00388 FT_Bytes table,
00389 FT_Bytes limit,
00390 GXV_Validator valid )
00391 {
00392 FT_UShort setMark;
00393 FT_UShort dontAdvance;
00394 FT_UShort markClass;
00395 FT_UShort currentClass;
00396
00397 FT_UNUSED( state );
00398 FT_UNUSED( glyphOffset_p );
00399 FT_UNUSED( table );
00400 FT_UNUSED( limit );
00401 FT_UNUSED( valid );
00402
00403
00404 setMark = (FT_UShort)( ( flags >> 15 ) & 1 );
00405 dontAdvance = (FT_UShort)( ( flags >> 14 ) & 1 );
00406 markClass = (FT_UShort)( ( flags >> 7 ) & 0x7F );
00407 currentClass = (FT_UShort)( flags & 0x7F );
00408
00409
00410 }
00411
00412
00413 static void
00414 gxv_just_justClassTable_validate ( FT_Bytes table,
00415 FT_Bytes limit,
00416 GXV_Validator valid )
00417 {
00418 FT_Bytes p = table;
00419 FT_UShort length;
00420 FT_UShort coverage;
00421 FT_ULong subFeatureFlags;
00422
00423
00424 GXV_NAME_ENTER( "just justClassTable" );
00425
00426 GXV_LIMIT_CHECK( 2 + 2 + 4 );
00427 length = FT_NEXT_USHORT( p );
00428 coverage = FT_NEXT_USHORT( p );
00429 subFeatureFlags = FT_NEXT_ULONG( p );
00430
00431 GXV_TRACE(( " justClassTable: coverage = 0x%04x (%s)",
00432 coverage,
00433 ( 0x4000 & coverage ) == 0 ? "ascending" : "descending" ));
00434
00435 valid->statetable.optdata = NULL;
00436 valid->statetable.optdata_load_func = NULL;
00437 valid->statetable.subtable_setup_func = NULL;
00438 valid->statetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_NONE;
00439 valid->statetable.entry_validate_func =
00440 gxv_just_classTable_entry_validate;
00441
00442 gxv_StateTable_validate( p, table + length, valid );
00443
00444
00445
00446 GXV_EXIT;
00447 }
00448
00449
00450 static void
00451 gxv_just_wdcTable_LookupValue_validate( FT_UShort glyph,
00452 GXV_LookupValueCPtr value_p,
00453 GXV_Validator valid )
00454 {
00455 FT_UNUSED( glyph );
00456
00457 if ( value_p->u > GXV_JUST_DATA( wdc_offset_max ) )
00458 GXV_JUST_DATA( wdc_offset_max ) = value_p->u;
00459 if ( value_p->u < GXV_JUST_DATA( wdc_offset_min ) )
00460 GXV_JUST_DATA( wdc_offset_min ) = value_p->u;
00461 }
00462
00463
00464 static void
00465 gxv_just_justData_lookuptable_validate( FT_Bytes table,
00466 FT_Bytes limit,
00467 GXV_Validator valid )
00468 {
00469 FT_Bytes p = table;
00470
00471
00472 GXV_JUST_DATA( wdc_offset_max ) = 0x0000;
00473 GXV_JUST_DATA( wdc_offset_min ) = 0xFFFFU;
00474
00475 valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED;
00476 valid->lookupval_func = gxv_just_wdcTable_LookupValue_validate;
00477
00478 gxv_LookupTable_validate( p, limit, valid );
00479
00480
00481
00482 GXV_EXIT;
00483 }
00484
00485
00486
00487
00488
00489 static void
00490 gxv_just_justData_validate( FT_Bytes table,
00491 FT_Bytes limit,
00492 GXV_Validator valid )
00493 {
00494
00495
00496
00497
00498 FT_UShort justClassTableOffset;
00499 FT_UShort wdcTableOffset;
00500 FT_UShort pcTableOffset;
00501 FT_Bytes p = table;
00502
00503 GXV_ODTECT( 4, odtect );
00504
00505
00506 GXV_NAME_ENTER( "just justData" );
00507
00508 GXV_ODTECT_INIT( odtect );
00509 GXV_LIMIT_CHECK( 2 + 2 + 2 );
00510 justClassTableOffset = FT_NEXT_USHORT( p );
00511 wdcTableOffset = FT_NEXT_USHORT( p );
00512 pcTableOffset = FT_NEXT_USHORT( p );
00513
00514 GXV_TRACE(( " (justClassTableOffset = 0x%04x)\n", justClassTableOffset ));
00515 GXV_TRACE(( " (wdcTableOffset = 0x%04x)\n", wdcTableOffset ));
00516 GXV_TRACE(( " (pcTableOffset = 0x%04x)\n", pcTableOffset ));
00517
00518 gxv_just_justData_lookuptable_validate( p, limit, valid );
00519 gxv_odtect_add_range( p, valid->subtable_length,
00520 "just_LookupTable", odtect );
00521
00522 if ( wdcTableOffset )
00523 {
00524 gxv_just_widthDeltaClusters_validate(
00525 valid->root->base + wdcTableOffset, limit, valid );
00526 gxv_odtect_add_range( valid->root->base + wdcTableOffset,
00527 valid->subtable_length, "just_wdcTable", odtect );
00528 }
00529
00530 if ( pcTableOffset )
00531 {
00532 gxv_just_postcompTable_validate( valid->root->base + pcTableOffset,
00533 limit, valid );
00534 gxv_odtect_add_range( valid->root->base + pcTableOffset,
00535 valid->subtable_length, "just_pcTable", odtect );
00536 }
00537
00538 if ( justClassTableOffset )
00539 {
00540 gxv_just_justClassTable_validate(
00541 valid->root->base + justClassTableOffset, limit, valid );
00542 gxv_odtect_add_range( valid->root->base + justClassTableOffset,
00543 valid->subtable_length, "just_justClassTable",
00544 odtect );
00545 }
00546
00547 gxv_odtect_validate( odtect, valid );
00548
00549 GXV_EXIT;
00550 }
00551
00552
00553 FT_LOCAL_DEF( void )
00554 gxv_just_validate( FT_Bytes table,
00555 FT_Face face,
00556 FT_Validator ftvalid )
00557 {
00558 FT_Bytes p = table;
00559 FT_Bytes limit = 0;
00560 FT_Offset table_size;
00561
00562 GXV_ValidatorRec validrec;
00563 GXV_Validator valid = &validrec;
00564 GXV_just_DataRec justrec;
00565 GXV_just_Data just = &justrec;
00566
00567 FT_ULong version;
00568 FT_UShort format;
00569 FT_UShort horizOffset;
00570 FT_UShort vertOffset;
00571
00572 GXV_ODTECT( 3, odtect );
00573
00574
00575 GXV_ODTECT_INIT( odtect );
00576
00577 valid->root = ftvalid;
00578 valid->table_data = just;
00579 valid->face = face;
00580
00581 FT_TRACE3(( "validating `just' table\n" ));
00582 GXV_INIT;
00583
00584 limit = valid->root->limit;
00585 table_size = limit - table;
00586
00587 GXV_LIMIT_CHECK( 4 + 2 + 2 + 2 );
00588 version = FT_NEXT_ULONG( p );
00589 format = FT_NEXT_USHORT( p );
00590 horizOffset = FT_NEXT_USHORT( p );
00591 vertOffset = FT_NEXT_USHORT( p );
00592 gxv_odtect_add_range( table, p - table, "just header", odtect );
00593
00594
00595
00596 GXV_TRACE(( " (version = 0x%08x)\n", version ));
00597 if ( version != 0x00010000UL )
00598 FT_INVALID_FORMAT;
00599
00600
00601 GXV_TRACE(( " (format = 0x%04x)\n", format ));
00602 if ( format != 0x0000 )
00603 FT_INVALID_FORMAT;
00604
00605 GXV_TRACE(( " (horizOffset = %d)\n", horizOffset ));
00606 GXV_TRACE(( " (vertOffset = %d)\n", vertOffset ));
00607
00608
00609
00610 if ( 0 < horizOffset )
00611 {
00612 gxv_just_justData_validate( table + horizOffset, limit, valid );
00613 gxv_odtect_add_range( table + horizOffset, valid->subtable_length,
00614 "horizJustData", odtect );
00615 }
00616
00617 if ( 0 < vertOffset )
00618 {
00619 gxv_just_justData_validate( table + vertOffset, limit, valid );
00620 gxv_odtect_add_range( table + vertOffset, valid->subtable_length,
00621 "vertJustData", odtect );
00622 }
00623
00624 gxv_odtect_validate( odtect, valid );
00625
00626 FT_TRACE4(( "\n" ));
00627 }
00628
00629
00630