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