otvcommn.c

Go to the documentation of this file.
00001 /***************************************************************************/
00002 /*                                                                         */
00003 /*  otvcommn.c                                                             */
00004 /*                                                                         */
00005 /*    OpenType common tables validation (body).                            */
00006 /*                                                                         */
00007 /*  Copyright 2004, 2005, 2006, 2007 by                                    */
00008 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
00009 /*                                                                         */
00010 /*  This file is part of the FreeType project, and may only be used,       */
00011 /*  modified, and distributed under the terms of the FreeType project      */
00012 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
00013 /*  this file you indicate that you have read the license and              */
00014 /*  understand and accept it fully.                                        */
00015 /*                                                                         */
00016 /***************************************************************************/
00017 
00018 
00019 #include "otvcommn.h"
00020 
00021 
00022   /*************************************************************************/
00023   /*                                                                       */
00024   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
00025   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
00026   /* messages during execution.                                            */
00027   /*                                                                       */
00028 #undef  FT_COMPONENT
00029 #define FT_COMPONENT  trace_otvcommon
00030 
00031 
00032   /*************************************************************************/
00033   /*************************************************************************/
00034   /*****                                                               *****/
00035   /*****                       COVERAGE TABLE                          *****/
00036   /*****                                                               *****/
00037   /*************************************************************************/
00038   /*************************************************************************/
00039 
00040   FT_LOCAL_DEF( void )
00041   otv_Coverage_validate( FT_Bytes       table,
00042                          OTV_Validator  valid,
00043                          FT_Int         expected_count )
00044   {
00045     FT_Bytes  p = table;
00046     FT_UInt   CoverageFormat;
00047     FT_UInt   total = 0;
00048 
00049 
00050     OTV_NAME_ENTER( "Coverage" );
00051 
00052     OTV_LIMIT_CHECK( 4 );
00053     CoverageFormat = FT_NEXT_USHORT( p );
00054 
00055     OTV_TRACE(( " (format %d)\n", CoverageFormat ));
00056 
00057     switch ( CoverageFormat )
00058     {
00059     case 1:     /* CoverageFormat1 */
00060       {
00061         FT_UInt  GlyphCount;
00062         FT_UInt  i;
00063 
00064 
00065         GlyphCount = FT_NEXT_USHORT( p );
00066 
00067         OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount ));
00068 
00069         OTV_LIMIT_CHECK( GlyphCount * 2 );        /* GlyphArray */
00070 
00071         for ( i = 0; i < GlyphCount; ++i )
00072         {
00073           FT_UInt  gid;
00074 
00075 
00076           gid = FT_NEXT_USHORT( p );
00077           if ( gid >= valid->glyph_count )
00078             FT_INVALID_GLYPH_ID;
00079         }
00080 
00081         total = GlyphCount;
00082       }
00083       break;
00084 
00085     case 2:     /* CoverageFormat2 */
00086       {
00087         FT_UInt  n, RangeCount;
00088         FT_UInt  Start, End, StartCoverageIndex, last = 0;
00089 
00090 
00091         RangeCount = FT_NEXT_USHORT( p );
00092 
00093         OTV_TRACE(( " (RangeCount = %d)\n", RangeCount ));
00094 
00095         OTV_LIMIT_CHECK( RangeCount * 6 );
00096 
00097         /* RangeRecord */
00098         for ( n = 0; n < RangeCount; n++ )
00099         {
00100           Start              = FT_NEXT_USHORT( p );
00101           End                = FT_NEXT_USHORT( p );
00102           StartCoverageIndex = FT_NEXT_USHORT( p );
00103 
00104           if ( Start > End || StartCoverageIndex != total )
00105             FT_INVALID_DATA;
00106 
00107           if ( End >= valid->glyph_count )
00108             FT_INVALID_GLYPH_ID;
00109 
00110           if ( n > 0 && Start <= last )
00111             FT_INVALID_DATA;
00112 
00113           total += End - Start + 1;
00114           last   = End;
00115         }
00116       }
00117       break;
00118 
00119     default:
00120       FT_INVALID_FORMAT;
00121     }
00122 
00123     /* Generally, a coverage table offset has an associated count field.  */
00124     /* The number of glyphs in the table should match this field.  If     */
00125     /* there is no associated count, a value of -1 tells us not to check. */
00126     if ( expected_count != -1 && (FT_UInt)expected_count != total )
00127       FT_INVALID_DATA;
00128 
00129     OTV_EXIT;
00130   }
00131 
00132 
00133   FT_LOCAL_DEF( FT_UInt )
00134   otv_Coverage_get_first( FT_Bytes  table )
00135   {
00136     FT_Bytes  p = table;
00137 
00138 
00139     p += 4;     /* skip CoverageFormat and Glyph/RangeCount */
00140 
00141     return FT_NEXT_USHORT( p );
00142   }
00143 
00144 
00145   FT_LOCAL_DEF( FT_UInt )
00146   otv_Coverage_get_last( FT_Bytes  table )
00147   {
00148     FT_Bytes  p = table;
00149     FT_UInt   CoverageFormat = FT_NEXT_USHORT( p );
00150     FT_UInt   count          = FT_NEXT_USHORT( p );     /* Glyph/RangeCount */
00151     FT_UInt   result = 0;
00152 
00153 
00154     switch ( CoverageFormat )
00155     {
00156     case 1:
00157       p += ( count - 1 ) * 2;
00158       result = FT_NEXT_USHORT( p );
00159       break;
00160 
00161     case 2:
00162       p += ( count - 1 ) * 6 + 2;
00163       result = FT_NEXT_USHORT( p );
00164       break;
00165 
00166     default:
00167       ;
00168     }
00169 
00170     return result;
00171   }
00172 
00173 
00174   FT_LOCAL_DEF( FT_UInt )
00175   otv_Coverage_get_count( FT_Bytes  table )
00176   {
00177     FT_Bytes  p              = table;
00178     FT_UInt   CoverageFormat = FT_NEXT_USHORT( p );
00179     FT_UInt   count          = FT_NEXT_USHORT( p );     /* Glyph/RangeCount */
00180     FT_UInt   result         = 0;
00181 
00182 
00183     switch ( CoverageFormat )
00184     {
00185     case 1:
00186       return count;
00187 
00188     case 2:
00189       {
00190         FT_UInt  Start, End;
00191 
00192 
00193         for ( ; count > 0; count-- )
00194         {
00195           Start = FT_NEXT_USHORT( p );
00196           End   = FT_NEXT_USHORT( p );
00197           p    += 2;                    /* skip StartCoverageIndex */
00198 
00199           result += End - Start + 1;
00200         }
00201       }
00202       break;
00203 
00204     default:
00205       ;
00206     }
00207 
00208     return result;
00209   }
00210 
00211 
00212   /*************************************************************************/
00213   /*************************************************************************/
00214   /*****                                                               *****/
00215   /*****                   CLASS DEFINITION TABLE                      *****/
00216   /*****                                                               *****/
00217   /*************************************************************************/
00218   /*************************************************************************/
00219 
00220   FT_LOCAL_DEF( void )
00221   otv_ClassDef_validate( FT_Bytes       table,
00222                          OTV_Validator  valid )
00223   {
00224     FT_Bytes  p = table;
00225     FT_UInt   ClassFormat;
00226 
00227 
00228     OTV_NAME_ENTER( "ClassDef" );
00229 
00230     OTV_LIMIT_CHECK( 4 );
00231     ClassFormat = FT_NEXT_USHORT( p );
00232 
00233     OTV_TRACE(( " (format %d)\n", ClassFormat ));
00234 
00235     switch ( ClassFormat )
00236     {
00237     case 1:     /* ClassDefFormat1 */
00238       {
00239         FT_UInt  StartGlyph;
00240         FT_UInt  GlyphCount;
00241 
00242 
00243         OTV_LIMIT_CHECK( 4 );
00244 
00245         StartGlyph = FT_NEXT_USHORT( p );
00246         GlyphCount = FT_NEXT_USHORT( p );
00247 
00248         OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount ));
00249 
00250         OTV_LIMIT_CHECK( GlyphCount * 2 );    /* ClassValueArray */
00251 
00252         if ( StartGlyph + GlyphCount - 1 >= valid->glyph_count )
00253           FT_INVALID_GLYPH_ID;
00254       }
00255       break;
00256 
00257     case 2:     /* ClassDefFormat2 */
00258       {
00259         FT_UInt  n, ClassRangeCount;
00260         FT_UInt  Start, End, last = 0;
00261 
00262 
00263         ClassRangeCount = FT_NEXT_USHORT( p );
00264 
00265         OTV_TRACE(( " (ClassRangeCount = %d)\n", ClassRangeCount ));
00266 
00267         OTV_LIMIT_CHECK( ClassRangeCount * 6 );
00268 
00269         /* ClassRangeRecord */
00270         for ( n = 0; n < ClassRangeCount; n++ )
00271         {
00272           Start = FT_NEXT_USHORT( p );
00273           End   = FT_NEXT_USHORT( p );
00274           p    += 2;                        /* skip Class */
00275 
00276           if ( Start > End || ( n > 0 && Start <= last ) )
00277             FT_INVALID_DATA;
00278 
00279           if ( End >= valid->glyph_count )
00280             FT_INVALID_GLYPH_ID;
00281 
00282           last = End;
00283         }
00284       }
00285       break;
00286 
00287     default:
00288       FT_INVALID_FORMAT;
00289     }
00290 
00291     /* no need to check glyph indices used as input to class definition   */
00292     /* tables since even invalid glyph indices return a meaningful result */
00293 
00294     OTV_EXIT;
00295   }
00296 
00297 
00298   /*************************************************************************/
00299   /*************************************************************************/
00300   /*****                                                               *****/
00301   /*****                      DEVICE TABLE                             *****/
00302   /*****                                                               *****/
00303   /*************************************************************************/
00304   /*************************************************************************/
00305 
00306   FT_LOCAL_DEF( void )
00307   otv_Device_validate( FT_Bytes       table,
00308                        OTV_Validator  valid )
00309   {
00310     FT_Bytes  p = table;
00311     FT_UInt   StartSize, EndSize, DeltaFormat, count;
00312 
00313 
00314     OTV_NAME_ENTER( "Device" );
00315 
00316     OTV_LIMIT_CHECK( 8 );
00317     StartSize   = FT_NEXT_USHORT( p );
00318     EndSize     = FT_NEXT_USHORT( p );
00319     DeltaFormat = FT_NEXT_USHORT( p );
00320 
00321     if ( DeltaFormat < 1 || DeltaFormat > 3 )
00322       FT_INVALID_FORMAT;
00323 
00324     if ( EndSize < StartSize )
00325       FT_INVALID_DATA;
00326 
00327     count = EndSize - StartSize + 1;
00328     OTV_LIMIT_CHECK( ( 1 << DeltaFormat ) * count / 8 );  /* DeltaValue */
00329 
00330     OTV_EXIT;
00331   }
00332 
00333 
00334   /*************************************************************************/
00335   /*************************************************************************/
00336   /*****                                                               *****/
00337   /*****                         LOOKUPS                               *****/
00338   /*****                                                               *****/
00339   /*************************************************************************/
00340   /*************************************************************************/
00341 
00342   /* uses valid->type_count */
00343   /* uses valid->type_funcs */
00344 
00345   FT_LOCAL_DEF( void )
00346   otv_Lookup_validate( FT_Bytes       table,
00347                        OTV_Validator  valid )
00348   {
00349     FT_Bytes           p = table;
00350     FT_UInt            LookupType, SubTableCount;
00351     OTV_Validate_Func  validate;
00352 
00353 
00354     OTV_NAME_ENTER( "Lookup" );
00355 
00356     OTV_LIMIT_CHECK( 6 );
00357     LookupType    = FT_NEXT_USHORT( p );
00358     p            += 2;                      /* skip LookupFlag */
00359     SubTableCount = FT_NEXT_USHORT( p );
00360 
00361     OTV_TRACE(( " (type %d)\n", LookupType ));
00362 
00363     if ( LookupType == 0 || LookupType > valid->type_count )
00364       FT_INVALID_DATA;
00365 
00366     validate = valid->type_funcs[LookupType - 1];
00367 
00368     OTV_TRACE(( " (SubTableCount = %d)\n", SubTableCount ));
00369 
00370     OTV_LIMIT_CHECK( SubTableCount * 2 );
00371 
00372     /* SubTable */
00373     for ( ; SubTableCount > 0; SubTableCount-- )
00374       validate( table + FT_NEXT_USHORT( p ), valid );
00375 
00376     OTV_EXIT;
00377   }
00378 
00379 
00380   /* uses valid->lookup_count */
00381 
00382   FT_LOCAL_DEF( void )
00383   otv_LookupList_validate( FT_Bytes       table,
00384                            OTV_Validator  valid )
00385   {
00386     FT_Bytes  p = table;
00387     FT_UInt   LookupCount;
00388 
00389 
00390     OTV_NAME_ENTER( "LookupList" );
00391 
00392     OTV_LIMIT_CHECK( 2 );
00393     LookupCount = FT_NEXT_USHORT( p );
00394 
00395     OTV_TRACE(( " (LookupCount = %d)\n", LookupCount ));
00396 
00397     OTV_LIMIT_CHECK( LookupCount * 2 );
00398 
00399     valid->lookup_count = LookupCount;
00400 
00401     /* Lookup */
00402     for ( ; LookupCount > 0; LookupCount-- )
00403       otv_Lookup_validate( table + FT_NEXT_USHORT( p ), valid );
00404 
00405     OTV_EXIT;
00406   }
00407 
00408 
00409   static FT_UInt
00410   otv_LookupList_get_count( FT_Bytes  table )
00411   {
00412     return FT_NEXT_USHORT( table );
00413   }
00414 
00415 
00416   /*************************************************************************/
00417   /*************************************************************************/
00418   /*****                                                               *****/
00419   /*****                        FEATURES                               *****/
00420   /*****                                                               *****/
00421   /*************************************************************************/
00422   /*************************************************************************/
00423 
00424   /* uses valid->lookup_count */
00425 
00426   FT_LOCAL_DEF( void )
00427   otv_Feature_validate( FT_Bytes       table,
00428                         OTV_Validator  valid )
00429   {
00430     FT_Bytes  p = table;
00431     FT_UInt   LookupCount;
00432 
00433 
00434     OTV_NAME_ENTER( "Feature" );
00435 
00436     OTV_LIMIT_CHECK( 4 );
00437     p           += 2;                   /* skip FeatureParams (unused) */
00438     LookupCount  = FT_NEXT_USHORT( p );
00439 
00440     OTV_TRACE(( " (LookupCount = %d)\n", LookupCount ));
00441 
00442     OTV_LIMIT_CHECK( LookupCount * 2 );
00443 
00444     /* LookupListIndex */
00445     for ( ; LookupCount > 0; LookupCount-- )
00446       if ( FT_NEXT_USHORT( p ) >= valid->lookup_count )
00447         FT_INVALID_DATA;
00448 
00449     OTV_EXIT;
00450   }
00451 
00452 
00453   static FT_UInt
00454   otv_Feature_get_count( FT_Bytes  table )
00455   {
00456     return FT_NEXT_USHORT( table );
00457   }
00458 
00459 
00460   /* sets valid->lookup_count */
00461 
00462   FT_LOCAL_DEF( void )
00463   otv_FeatureList_validate( FT_Bytes       table,
00464                             FT_Bytes       lookups,
00465                             OTV_Validator  valid )
00466   {
00467     FT_Bytes  p = table;
00468     FT_UInt   FeatureCount;
00469 
00470 
00471     OTV_NAME_ENTER( "FeatureList" );
00472 
00473     OTV_LIMIT_CHECK( 2 );
00474     FeatureCount = FT_NEXT_USHORT( p );
00475 
00476     OTV_TRACE(( " (FeatureCount = %d)\n", FeatureCount ));
00477 
00478     OTV_LIMIT_CHECK( FeatureCount * 2 );
00479 
00480     valid->lookup_count = otv_LookupList_get_count( lookups );
00481 
00482     /* FeatureRecord */
00483     for ( ; FeatureCount > 0; FeatureCount-- )
00484     {
00485       p += 4;       /* skip FeatureTag */
00486 
00487       /* Feature */
00488       otv_Feature_validate( table + FT_NEXT_USHORT( p ), valid );
00489     }
00490 
00491     OTV_EXIT;
00492   }
00493 
00494 
00495   /*************************************************************************/
00496   /*************************************************************************/
00497   /*****                                                               *****/
00498   /*****                       LANGUAGE SYSTEM                         *****/
00499   /*****                                                               *****/
00500   /*************************************************************************/
00501   /*************************************************************************/
00502 
00503 
00504   /* uses valid->extra1 (number of features) */
00505 
00506   FT_LOCAL_DEF( void )
00507   otv_LangSys_validate( FT_Bytes       table,
00508                         OTV_Validator  valid )
00509   {
00510     FT_Bytes  p = table;
00511     FT_UInt   ReqFeatureIndex;
00512     FT_UInt   FeatureCount;
00513 
00514 
00515     OTV_NAME_ENTER( "LangSys" );
00516 
00517     OTV_LIMIT_CHECK( 6 );
00518     p              += 2;                    /* skip LookupOrder (unused) */
00519     ReqFeatureIndex = FT_NEXT_USHORT( p );
00520     FeatureCount    = FT_NEXT_USHORT( p );
00521 
00522     OTV_TRACE(( " (ReqFeatureIndex = %d)\n", ReqFeatureIndex ));
00523     OTV_TRACE(( " (FeatureCount = %d)\n",    FeatureCount    ));
00524 
00525     if ( ReqFeatureIndex != 0xFFFFU && ReqFeatureIndex >= valid->extra1 )
00526       FT_INVALID_DATA;
00527 
00528     OTV_LIMIT_CHECK( FeatureCount * 2 );
00529 
00530     /* FeatureIndex */
00531     for ( ; FeatureCount > 0; FeatureCount-- )
00532       if ( FT_NEXT_USHORT( p ) >= valid->extra1 )
00533         FT_INVALID_DATA;
00534 
00535     OTV_EXIT;
00536   }
00537 
00538 
00539   /*************************************************************************/
00540   /*************************************************************************/
00541   /*****                                                               *****/
00542   /*****                           SCRIPTS                             *****/
00543   /*****                                                               *****/
00544   /*************************************************************************/
00545   /*************************************************************************/
00546 
00547   FT_LOCAL_DEF( void )
00548   otv_Script_validate( FT_Bytes       table,
00549                        OTV_Validator  valid )
00550   {
00551     FT_UInt   DefaultLangSys, LangSysCount;
00552     FT_Bytes  p = table;
00553 
00554 
00555     OTV_NAME_ENTER( "Script" );
00556 
00557     OTV_LIMIT_CHECK( 4 );
00558     DefaultLangSys = FT_NEXT_USHORT( p );
00559     LangSysCount   = FT_NEXT_USHORT( p );
00560 
00561     OTV_TRACE(( " (LangSysCount = %d)\n", LangSysCount ));
00562 
00563     if ( DefaultLangSys != 0 )
00564       otv_LangSys_validate( table + DefaultLangSys, valid );
00565 
00566     OTV_LIMIT_CHECK( LangSysCount * 6 );
00567 
00568     /* LangSysRecord */
00569     for ( ; LangSysCount > 0; LangSysCount-- )
00570     {
00571       p += 4;       /* skip LangSysTag */
00572 
00573       /* LangSys */
00574       otv_LangSys_validate( table + FT_NEXT_USHORT( p ), valid );
00575     }
00576 
00577     OTV_EXIT;
00578   }
00579 
00580 
00581   /* sets valid->extra1 (number of features) */
00582 
00583   FT_LOCAL_DEF( void )
00584   otv_ScriptList_validate( FT_Bytes       table,
00585                            FT_Bytes       features,
00586                            OTV_Validator  valid )
00587   {
00588     FT_UInt   ScriptCount;
00589     FT_Bytes  p = table;
00590 
00591 
00592     OTV_NAME_ENTER( "ScriptList" );
00593 
00594     OTV_LIMIT_CHECK( 2 );
00595     ScriptCount = FT_NEXT_USHORT( p );
00596 
00597     OTV_TRACE(( " (ScriptCount = %d)\n", ScriptCount ));
00598 
00599     OTV_LIMIT_CHECK( ScriptCount * 6 );
00600 
00601     valid->extra1 = otv_Feature_get_count( features );
00602 
00603     /* ScriptRecord */
00604     for ( ; ScriptCount > 0; ScriptCount-- )
00605     {
00606       p += 4;       /* skip ScriptTag */
00607 
00608       otv_Script_validate( table + FT_NEXT_USHORT( p ), valid ); /* Script */
00609     }
00610 
00611     OTV_EXIT;
00612   }
00613 
00614 
00615   /*************************************************************************/
00616   /*************************************************************************/
00617   /*****                                                               *****/
00618   /*****                      UTILITY FUNCTIONS                        *****/
00619   /*****                                                               *****/
00620   /*************************************************************************/
00621   /*************************************************************************/
00622 
00623   /*
00624      u:   uint16
00625      ux:  unit16 [x]
00626 
00627      s:   struct
00628      sx:  struct [x]
00629      sxy: struct [x], using external y count
00630 
00631      x:   uint16 x
00632 
00633      C:   Coverage
00634 
00635      O:   Offset
00636      On:  Offset (NULL)
00637      Ox:  Offset [x]
00638      Onx: Offset (NULL) [x]
00639   */
00640 
00641   FT_LOCAL_DEF( void )
00642   otv_x_Ox( FT_Bytes       table,
00643             OTV_Validator  valid )
00644   {
00645     FT_Bytes           p = table;
00646     FT_UInt            Count;
00647     OTV_Validate_Func  func;
00648 
00649 
00650     OTV_ENTER;
00651 
00652     OTV_LIMIT_CHECK( 2 );
00653     Count = FT_NEXT_USHORT( p );
00654 
00655     OTV_TRACE(( " (Count = %d)\n", Count ));
00656 
00657     OTV_LIMIT_CHECK( Count * 2 );
00658 
00659     valid->nesting_level++;
00660     func = valid->func[valid->nesting_level];
00661 
00662     for ( ; Count > 0; Count-- )
00663       func( table + FT_NEXT_USHORT( p ), valid );
00664 
00665     valid->nesting_level--;
00666 
00667     OTV_EXIT;
00668   }
00669 
00670 
00671   FT_LOCAL_DEF( void )
00672   otv_u_C_x_Ox( FT_Bytes       table,
00673                 OTV_Validator  valid )
00674   {
00675     FT_Bytes           p = table;
00676     FT_UInt            Count, Coverage;
00677     OTV_Validate_Func  func;
00678 
00679 
00680     OTV_ENTER;
00681 
00682     p += 2;     /* skip Format */
00683 
00684     OTV_LIMIT_CHECK( 4 );
00685     Coverage = FT_NEXT_USHORT( p );
00686     Count    = FT_NEXT_USHORT( p );
00687 
00688     OTV_TRACE(( " (Count = %d)\n", Count ));
00689 
00690     otv_Coverage_validate( table + Coverage, valid, Count );
00691 
00692     OTV_LIMIT_CHECK( Count * 2 );
00693 
00694     valid->nesting_level++;
00695     func = valid->func[valid->nesting_level];
00696 
00697     for ( ; Count > 0; Count-- )
00698       func( table + FT_NEXT_USHORT( p ), valid );
00699 
00700     valid->nesting_level--;
00701 
00702     OTV_EXIT;
00703   }
00704 
00705 
00706   /* uses valid->extra1 (if > 0: array value limit) */
00707 
00708   FT_LOCAL_DEF( void )
00709   otv_x_ux( FT_Bytes       table,
00710             OTV_Validator  valid )
00711   {
00712     FT_Bytes  p = table;
00713     FT_UInt   Count;
00714 
00715 
00716     OTV_ENTER;
00717 
00718     OTV_LIMIT_CHECK( 2 );
00719     Count = FT_NEXT_USHORT( p );
00720 
00721     OTV_TRACE(( " (Count = %d)\n", Count ));
00722 
00723     OTV_LIMIT_CHECK( Count * 2 );
00724 
00725     if ( valid->extra1 )
00726     {
00727       for ( ; Count > 0; Count-- )
00728         if ( FT_NEXT_USHORT( p ) >= valid->extra1 )
00729           FT_INVALID_DATA;
00730     }
00731 
00732     OTV_EXIT;
00733   }
00734 
00735 
00736   /* `ux' in the function's name is not really correct since only x-1 */
00737   /* elements are tested                                              */
00738 
00739   /* uses valid->extra1 (array value limit) */
00740 
00741   FT_LOCAL_DEF( void )
00742   otv_x_y_ux_sy( FT_Bytes       table,
00743                  OTV_Validator  valid )
00744   {
00745     FT_Bytes  p = table;
00746     FT_UInt   Count1, Count2;
00747 
00748 
00749     OTV_ENTER;
00750 
00751     OTV_LIMIT_CHECK( 4 );
00752     Count1 = FT_NEXT_USHORT( p );
00753     Count2 = FT_NEXT_USHORT( p );
00754 
00755     OTV_TRACE(( " (Count1 = %d)\n", Count1 ));
00756     OTV_TRACE(( " (Count2 = %d)\n", Count2 ));
00757 
00758     if ( Count1 == 0 )
00759       FT_INVALID_DATA;
00760 
00761     OTV_LIMIT_CHECK( ( Count1 - 1 ) * 2 + Count2 * 4 );
00762     p += ( Count1 - 1 ) * 2;
00763 
00764     for ( ; Count2 > 0; Count2-- )
00765     {
00766       if ( FT_NEXT_USHORT( p ) >= Count1 )
00767         FT_INVALID_DATA;
00768 
00769       if ( FT_NEXT_USHORT( p ) >= valid->extra1 )
00770         FT_INVALID_DATA;
00771     }
00772 
00773     OTV_EXIT;
00774   }
00775 
00776 
00777   /* `uy' in the function's name is not really correct since only y-1 */
00778   /* elements are tested                                              */
00779 
00780   /* uses valid->extra1 (array value limit) */
00781 
00782   FT_LOCAL_DEF( void )
00783   otv_x_ux_y_uy_z_uz_p_sp( FT_Bytes       table,
00784                            OTV_Validator  valid )
00785   {
00786     FT_Bytes  p = table;
00787     FT_UInt   BacktrackCount, InputCount, LookaheadCount;
00788     FT_UInt   Count;
00789 
00790 
00791     OTV_ENTER;
00792 
00793     OTV_LIMIT_CHECK( 2 );
00794     BacktrackCount = FT_NEXT_USHORT( p );
00795 
00796     OTV_TRACE(( " (BacktrackCount = %d)\n", BacktrackCount ));
00797 
00798     OTV_LIMIT_CHECK( BacktrackCount * 2 + 2 );
00799     p += BacktrackCount * 2;
00800 
00801     InputCount = FT_NEXT_USHORT( p );
00802     if ( InputCount == 0 )
00803       FT_INVALID_DATA;
00804 
00805     OTV_TRACE(( " (InputCount = %d)\n", InputCount ));
00806 
00807     OTV_LIMIT_CHECK( InputCount * 2 );
00808     p += ( InputCount - 1 ) * 2;
00809 
00810     LookaheadCount = FT_NEXT_USHORT( p );
00811 
00812     OTV_TRACE(( " (LookaheadCount = %d)\n", LookaheadCount ));
00813 
00814     OTV_LIMIT_CHECK( LookaheadCount * 2 + 2 );
00815     p += LookaheadCount * 2;
00816 
00817     Count = FT_NEXT_USHORT( p );
00818 
00819     OTV_TRACE(( " (Count = %d)\n", Count ));
00820 
00821     OTV_LIMIT_CHECK( Count * 4 );
00822 
00823     for ( ; Count > 0; Count-- )
00824     {
00825       if ( FT_NEXT_USHORT( p ) >= InputCount )
00826         FT_INVALID_DATA;
00827 
00828       if ( FT_NEXT_USHORT( p ) >= valid->extra1 )
00829         FT_INVALID_DATA;
00830     }
00831 
00832     OTV_EXIT;
00833   }
00834 
00835 
00836   /* sets valid->extra1 (valid->lookup_count) */
00837 
00838   FT_LOCAL_DEF( void )
00839   otv_u_O_O_x_Onx( FT_Bytes       table,
00840                    OTV_Validator  valid )
00841   {
00842     FT_Bytes           p = table;
00843     FT_UInt            Coverage, ClassDef, ClassSetCount;
00844     OTV_Validate_Func  func;
00845 
00846 
00847     OTV_ENTER;
00848 
00849     p += 2;     /* skip Format */
00850 
00851     OTV_LIMIT_CHECK( 6 );
00852     Coverage      = FT_NEXT_USHORT( p );
00853     ClassDef      = FT_NEXT_USHORT( p );
00854     ClassSetCount = FT_NEXT_USHORT( p );
00855 
00856     OTV_TRACE(( " (ClassSetCount = %d)\n", ClassSetCount ));
00857 
00858     otv_Coverage_validate( table + Coverage, valid, -1 );
00859     otv_ClassDef_validate( table + ClassDef, valid );
00860 
00861     OTV_LIMIT_CHECK( ClassSetCount * 2 );
00862 
00863     valid->nesting_level++;
00864     func          = valid->func[valid->nesting_level];
00865     valid->extra1 = valid->lookup_count;
00866 
00867     for ( ; ClassSetCount > 0; ClassSetCount-- )
00868     {
00869       FT_UInt  offset = FT_NEXT_USHORT( p );
00870 
00871 
00872       if ( offset )
00873         func( table + offset, valid );
00874     }
00875 
00876     valid->nesting_level--;
00877 
00878     OTV_EXIT;
00879   }
00880 
00881 
00882   /* uses valid->lookup_count */
00883 
00884   FT_LOCAL_DEF( void )
00885   otv_u_x_y_Ox_sy( FT_Bytes       table,
00886                    OTV_Validator  valid )
00887   {
00888     FT_Bytes  p = table;
00889     FT_UInt   GlyphCount, Count, count1;
00890 
00891 
00892     OTV_ENTER;
00893 
00894     p += 2;     /* skip Format */
00895 
00896     OTV_LIMIT_CHECK( 4 );
00897     GlyphCount = FT_NEXT_USHORT( p );
00898     Count      = FT_NEXT_USHORT( p );
00899 
00900     OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount ));
00901     OTV_TRACE(( " (Count = %d)\n",      Count      ));
00902 
00903     OTV_LIMIT_CHECK( GlyphCount * 2 + Count * 4 );
00904 
00905     for ( count1 = GlyphCount; count1 > 0; count1-- )
00906       otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 );
00907 
00908     for ( ; Count > 0; Count-- )
00909     {
00910       if ( FT_NEXT_USHORT( p ) >= GlyphCount )
00911         FT_INVALID_DATA;
00912 
00913       if ( FT_NEXT_USHORT( p ) >= valid->lookup_count )
00914         FT_INVALID_DATA;
00915     }
00916 
00917     OTV_EXIT;
00918   }
00919 
00920 
00921   /* sets valid->extra1 (valid->lookup_count)    */
00922 
00923   FT_LOCAL_DEF( void )
00924   otv_u_O_O_O_O_x_Onx( FT_Bytes       table,
00925                        OTV_Validator  valid )
00926   {
00927     FT_Bytes           p = table;
00928     FT_UInt            Coverage;
00929     FT_UInt            BacktrackClassDef, InputClassDef, LookaheadClassDef;
00930     FT_UInt            ChainClassSetCount;
00931     OTV_Validate_Func  func;
00932 
00933 
00934     OTV_ENTER;
00935 
00936     p += 2;     /* skip Format */
00937 
00938     OTV_LIMIT_CHECK( 10 );
00939     Coverage           = FT_NEXT_USHORT( p );
00940     BacktrackClassDef  = FT_NEXT_USHORT( p );
00941     InputClassDef      = FT_NEXT_USHORT( p );
00942     LookaheadClassDef  = FT_NEXT_USHORT( p );
00943     ChainClassSetCount = FT_NEXT_USHORT( p );
00944 
00945     OTV_TRACE(( " (ChainClassSetCount = %d)\n", ChainClassSetCount ));
00946 
00947     otv_Coverage_validate( table + Coverage, valid, -1 );
00948 
00949     otv_ClassDef_validate( table + BacktrackClassDef,  valid );
00950     otv_ClassDef_validate( table + InputClassDef, valid );
00951     otv_ClassDef_validate( table + LookaheadClassDef, valid );
00952 
00953     OTV_LIMIT_CHECK( ChainClassSetCount * 2 );
00954 
00955     valid->nesting_level++;
00956     func          = valid->func[valid->nesting_level];
00957     valid->extra1 = valid->lookup_count;
00958 
00959     for ( ; ChainClassSetCount > 0; ChainClassSetCount-- )
00960     {
00961       FT_UInt  offset = FT_NEXT_USHORT( p );
00962 
00963 
00964       if ( offset )
00965         func( table + offset, valid );
00966     }
00967 
00968     valid->nesting_level--;
00969 
00970     OTV_EXIT;
00971   }
00972 
00973 
00974   /* uses valid->lookup_count */
00975 
00976   FT_LOCAL_DEF( void )
00977   otv_u_x_Ox_y_Oy_z_Oz_p_sp( FT_Bytes       table,
00978                              OTV_Validator  valid )
00979   {
00980     FT_Bytes  p = table;
00981     FT_UInt   BacktrackGlyphCount, InputGlyphCount, LookaheadGlyphCount;
00982     FT_UInt   count1, count2;
00983 
00984 
00985     OTV_ENTER;
00986 
00987     p += 2;     /* skip Format */
00988 
00989     OTV_LIMIT_CHECK( 2 );
00990     BacktrackGlyphCount = FT_NEXT_USHORT( p );
00991 
00992     OTV_TRACE(( " (BacktrackGlyphCount = %d)\n", BacktrackGlyphCount ));
00993 
00994     OTV_LIMIT_CHECK( BacktrackGlyphCount * 2 + 2 );
00995 
00996     for ( ; BacktrackGlyphCount > 0; BacktrackGlyphCount-- )
00997       otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 );
00998 
00999     InputGlyphCount = FT_NEXT_USHORT( p );
01000 
01001     OTV_TRACE(( " (InputGlyphCount = %d)\n", InputGlyphCount ));
01002 
01003     OTV_LIMIT_CHECK( InputGlyphCount * 2 + 2 );
01004 
01005     for ( count1 = InputGlyphCount; count1 > 0; count1-- )
01006       otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 );
01007 
01008     LookaheadGlyphCount = FT_NEXT_USHORT( p );
01009 
01010     OTV_TRACE(( " (LookaheadGlyphCount = %d)\n", LookaheadGlyphCount ));
01011 
01012     OTV_LIMIT_CHECK( LookaheadGlyphCount * 2 + 2 );
01013 
01014     for ( ; LookaheadGlyphCount > 0; LookaheadGlyphCount-- )
01015       otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 );
01016 
01017     count2 = FT_NEXT_USHORT( p );
01018 
01019     OTV_TRACE(( " (Count = %d)\n", count2 ));
01020 
01021     OTV_LIMIT_CHECK( count2 * 4 );
01022 
01023     for ( ; count2 > 0; count2-- )
01024     {
01025       if ( FT_NEXT_USHORT( p ) >= InputGlyphCount )
01026         FT_INVALID_DATA;
01027 
01028       if ( FT_NEXT_USHORT( p ) >= valid->lookup_count )
01029         FT_INVALID_DATA;
01030     }
01031 
01032     OTV_EXIT;
01033   }
01034 
01035 
01036   FT_LOCAL_DEF( FT_UInt )
01037   otv_GSUBGPOS_get_Lookup_count( FT_Bytes  table )
01038   {
01039     FT_Bytes  p = table + 8;
01040 
01041 
01042     return otv_LookupList_get_count( table + FT_NEXT_USHORT( p ) );
01043   }
01044 
01045 
01046   FT_LOCAL_DEF( FT_UInt )
01047   otv_GSUBGPOS_have_MarkAttachmentType_flag( FT_Bytes  table )
01048   {
01049     FT_Bytes  p, lookup;
01050     FT_UInt   count;
01051 
01052 
01053     if ( !table )
01054       return 0;
01055 
01056     /* LookupList */
01057     p      = table + 8;
01058     table += FT_NEXT_USHORT( p );
01059 
01060     /* LookupCount */
01061     p     = table;
01062     count = FT_NEXT_USHORT( p );
01063 
01064     for ( ; count > 0; count-- )
01065     {
01066       FT_Bytes  oldp;
01067 
01068 
01069       /* Lookup */
01070       lookup = table + FT_NEXT_USHORT( p );
01071 
01072       oldp = p;
01073 
01074       /* LookupFlag */
01075       p = lookup + 2;
01076       if ( FT_NEXT_USHORT( p ) & 0xFF00U )
01077         return 1;
01078 
01079       p = oldp;
01080     }
01081 
01082     return 0;
01083   }
01084 
01085 
01086 /* END */

Generated on Tue Jul 5 14:13:48 2011 for ROOT_528-00b_version by  doxygen 1.5.1