Home | History | Annotate | Download | only in otvalid
      1 /***************************************************************************/
      2 /*                                                                         */
      3 /*  otvbase.c                                                              */
      4 /*                                                                         */
      5 /*    OpenType BASE table validation (body).                               */
      6 /*                                                                         */
      7 /*  Copyright 2004-2018 by                                                 */
      8 /*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
      9 /*                                                                         */
     10 /*  This file is part of the FreeType project, and may only be used,       */
     11 /*  modified, and distributed under the terms of the FreeType project      */
     12 /*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
     13 /*  this file you indicate that you have read the license and              */
     14 /*  understand and accept it fully.                                        */
     15 /*                                                                         */
     16 /***************************************************************************/
     17 
     18 
     19 #include "otvalid.h"
     20 #include "otvcommn.h"
     21 
     22 
     23   /*************************************************************************/
     24   /*                                                                       */
     25   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
     26   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
     27   /* messages during execution.                                            */
     28   /*                                                                       */
     29 #undef  FT_COMPONENT
     30 #define FT_COMPONENT  trace_otvbase
     31 
     32 
     33   static void
     34   otv_BaseCoord_validate( FT_Bytes       table,
     35                           OTV_Validator  otvalid )
     36   {
     37     FT_Bytes  p = table;
     38     FT_UInt   BaseCoordFormat;
     39 
     40 
     41     OTV_NAME_ENTER( "BaseCoord" );
     42 
     43     OTV_LIMIT_CHECK( 4 );
     44     BaseCoordFormat = FT_NEXT_USHORT( p );
     45     p += 2;     /* skip Coordinate */
     46 
     47     OTV_TRACE(( " (format %d)\n", BaseCoordFormat ));
     48 
     49     switch ( BaseCoordFormat )
     50     {
     51     case 1:     /* BaseCoordFormat1 */
     52       break;
     53 
     54     case 2:     /* BaseCoordFormat2 */
     55       OTV_LIMIT_CHECK( 4 );   /* ReferenceGlyph, BaseCoordPoint */
     56       break;
     57 
     58     case 3:     /* BaseCoordFormat3 */
     59       OTV_LIMIT_CHECK( 2 );
     60       /* DeviceTable */
     61       otv_Device_validate( table + FT_NEXT_USHORT( p ), otvalid );
     62       break;
     63 
     64     default:
     65       FT_INVALID_FORMAT;
     66     }
     67 
     68     OTV_EXIT;
     69   }
     70 
     71 
     72   static void
     73   otv_BaseTagList_validate( FT_Bytes       table,
     74                             OTV_Validator  otvalid )
     75   {
     76     FT_Bytes  p = table;
     77     FT_UInt   BaseTagCount;
     78 
     79 
     80     OTV_NAME_ENTER( "BaseTagList" );
     81 
     82     OTV_LIMIT_CHECK( 2 );
     83 
     84     BaseTagCount = FT_NEXT_USHORT( p );
     85 
     86     OTV_TRACE(( " (BaseTagCount = %d)\n", BaseTagCount ));
     87 
     88     OTV_LIMIT_CHECK( BaseTagCount * 4 );          /* BaselineTag */
     89 
     90     OTV_EXIT;
     91   }
     92 
     93 
     94   static void
     95   otv_BaseValues_validate( FT_Bytes       table,
     96                            OTV_Validator  otvalid )
     97   {
     98     FT_Bytes  p = table;
     99     FT_UInt   BaseCoordCount;
    100 
    101 
    102     OTV_NAME_ENTER( "BaseValues" );
    103 
    104     OTV_LIMIT_CHECK( 4 );
    105 
    106     p             += 2;                     /* skip DefaultIndex */
    107     BaseCoordCount = FT_NEXT_USHORT( p );
    108 
    109     OTV_TRACE(( " (BaseCoordCount = %d)\n", BaseCoordCount ));
    110 
    111     OTV_LIMIT_CHECK( BaseCoordCount * 2 );
    112 
    113     /* BaseCoord */
    114     for ( ; BaseCoordCount > 0; BaseCoordCount-- )
    115       otv_BaseCoord_validate( table + FT_NEXT_USHORT( p ), otvalid );
    116 
    117     OTV_EXIT;
    118   }
    119 
    120 
    121   static void
    122   otv_MinMax_validate( FT_Bytes       table,
    123                        OTV_Validator  otvalid )
    124   {
    125     FT_Bytes  p = table;
    126     FT_UInt   table_size;
    127     FT_UInt   FeatMinMaxCount;
    128 
    129     OTV_OPTIONAL_TABLE( MinCoord );
    130     OTV_OPTIONAL_TABLE( MaxCoord );
    131 
    132 
    133     OTV_NAME_ENTER( "MinMax" );
    134 
    135     OTV_LIMIT_CHECK( 6 );
    136 
    137     OTV_OPTIONAL_OFFSET( MinCoord );
    138     OTV_OPTIONAL_OFFSET( MaxCoord );
    139     FeatMinMaxCount = FT_NEXT_USHORT( p );
    140 
    141     OTV_TRACE(( " (FeatMinMaxCount = %d)\n", FeatMinMaxCount ));
    142 
    143     table_size = FeatMinMaxCount * 8 + 6;
    144 
    145     OTV_SIZE_CHECK( MinCoord );
    146     if ( MinCoord )
    147       otv_BaseCoord_validate( table + MinCoord, otvalid );
    148 
    149     OTV_SIZE_CHECK( MaxCoord );
    150     if ( MaxCoord )
    151       otv_BaseCoord_validate( table + MaxCoord, otvalid );
    152 
    153     OTV_LIMIT_CHECK( FeatMinMaxCount * 8 );
    154 
    155     /* FeatMinMaxRecord */
    156     for ( ; FeatMinMaxCount > 0; FeatMinMaxCount-- )
    157     {
    158       p += 4;                           /* skip FeatureTableTag */
    159 
    160       OTV_OPTIONAL_OFFSET( MinCoord );
    161       OTV_OPTIONAL_OFFSET( MaxCoord );
    162 
    163       OTV_SIZE_CHECK( MinCoord );
    164       if ( MinCoord )
    165         otv_BaseCoord_validate( table + MinCoord, otvalid );
    166 
    167       OTV_SIZE_CHECK( MaxCoord );
    168       if ( MaxCoord )
    169         otv_BaseCoord_validate( table + MaxCoord, otvalid );
    170     }
    171 
    172     OTV_EXIT;
    173   }
    174 
    175 
    176   static void
    177   otv_BaseScript_validate( FT_Bytes       table,
    178                            OTV_Validator  otvalid )
    179   {
    180     FT_Bytes  p = table;
    181     FT_UInt   table_size;
    182     FT_UInt   BaseLangSysCount;
    183 
    184     OTV_OPTIONAL_TABLE( BaseValues    );
    185     OTV_OPTIONAL_TABLE( DefaultMinMax );
    186 
    187 
    188     OTV_NAME_ENTER( "BaseScript" );
    189 
    190     OTV_LIMIT_CHECK( 6 );
    191     OTV_OPTIONAL_OFFSET( BaseValues    );
    192     OTV_OPTIONAL_OFFSET( DefaultMinMax );
    193     BaseLangSysCount = FT_NEXT_USHORT( p );
    194 
    195     OTV_TRACE(( " (BaseLangSysCount = %d)\n", BaseLangSysCount ));
    196 
    197     table_size = BaseLangSysCount * 6 + 6;
    198 
    199     OTV_SIZE_CHECK( BaseValues );
    200     if ( BaseValues )
    201       otv_BaseValues_validate( table + BaseValues, otvalid );
    202 
    203     OTV_SIZE_CHECK( DefaultMinMax );
    204     if ( DefaultMinMax )
    205       otv_MinMax_validate( table + DefaultMinMax, otvalid );
    206 
    207     OTV_LIMIT_CHECK( BaseLangSysCount * 6 );
    208 
    209     /* BaseLangSysRecord */
    210     for ( ; BaseLangSysCount > 0; BaseLangSysCount-- )
    211     {
    212       p += 4;       /* skip BaseLangSysTag */
    213 
    214       otv_MinMax_validate( table + FT_NEXT_USHORT( p ), otvalid );
    215     }
    216 
    217     OTV_EXIT;
    218   }
    219 
    220 
    221   static void
    222   otv_BaseScriptList_validate( FT_Bytes       table,
    223                                OTV_Validator  otvalid )
    224   {
    225     FT_Bytes  p = table;
    226     FT_UInt   BaseScriptCount;
    227 
    228 
    229     OTV_NAME_ENTER( "BaseScriptList" );
    230 
    231     OTV_LIMIT_CHECK( 2 );
    232     BaseScriptCount = FT_NEXT_USHORT( p );
    233 
    234     OTV_TRACE(( " (BaseScriptCount = %d)\n", BaseScriptCount ));
    235 
    236     OTV_LIMIT_CHECK( BaseScriptCount * 6 );
    237 
    238     /* BaseScriptRecord */
    239     for ( ; BaseScriptCount > 0; BaseScriptCount-- )
    240     {
    241       p += 4;       /* skip BaseScriptTag */
    242 
    243       /* BaseScript */
    244       otv_BaseScript_validate( table + FT_NEXT_USHORT( p ), otvalid );
    245     }
    246 
    247     OTV_EXIT;
    248   }
    249 
    250 
    251   static void
    252   otv_Axis_validate( FT_Bytes       table,
    253                      OTV_Validator  otvalid )
    254   {
    255     FT_Bytes  p = table;
    256     FT_UInt   table_size;
    257 
    258     OTV_OPTIONAL_TABLE( BaseTagList );
    259 
    260 
    261     OTV_NAME_ENTER( "Axis" );
    262 
    263     OTV_LIMIT_CHECK( 4 );
    264     OTV_OPTIONAL_OFFSET( BaseTagList );
    265 
    266     table_size = 4;
    267 
    268     OTV_SIZE_CHECK( BaseTagList );
    269     if ( BaseTagList )
    270       otv_BaseTagList_validate( table + BaseTagList, otvalid );
    271 
    272     /* BaseScriptList */
    273     otv_BaseScriptList_validate( table + FT_NEXT_USHORT( p ), otvalid );
    274 
    275     OTV_EXIT;
    276   }
    277 
    278 
    279   FT_LOCAL_DEF( void )
    280   otv_BASE_validate( FT_Bytes      table,
    281                      FT_Validator  ftvalid )
    282   {
    283     OTV_ValidatorRec  otvalidrec;
    284     OTV_Validator     otvalid = &otvalidrec;
    285     FT_Bytes          p       = table;
    286     FT_UInt           table_size;
    287     FT_UShort         version;
    288 
    289     OTV_OPTIONAL_TABLE( HorizAxis );
    290     OTV_OPTIONAL_TABLE( VertAxis  );
    291 
    292     OTV_OPTIONAL_TABLE32( itemVarStore );
    293 
    294 
    295     otvalid->root = ftvalid;
    296 
    297     FT_TRACE3(( "validating BASE table\n" ));
    298     OTV_INIT;
    299 
    300     OTV_LIMIT_CHECK( 4 );
    301 
    302     if ( FT_NEXT_USHORT( p ) != 1 )  /* majorVersion */
    303       FT_INVALID_FORMAT;
    304 
    305     version = FT_NEXT_USHORT( p );   /* minorVersion */
    306 
    307     table_size = 8;
    308     switch ( version )
    309     {
    310     case 0:
    311       OTV_LIMIT_CHECK( 4 );
    312       break;
    313 
    314     case 1:
    315       OTV_LIMIT_CHECK( 8 );
    316       table_size += 4;
    317       break;
    318 
    319     default:
    320       FT_INVALID_FORMAT;
    321     }
    322 
    323     OTV_OPTIONAL_OFFSET( HorizAxis );
    324     OTV_SIZE_CHECK( HorizAxis );
    325     if ( HorizAxis )
    326       otv_Axis_validate( table + HorizAxis, otvalid );
    327 
    328     OTV_OPTIONAL_OFFSET( VertAxis );
    329     OTV_SIZE_CHECK( VertAxis );
    330     if ( VertAxis )
    331       otv_Axis_validate( table + VertAxis, otvalid );
    332 
    333     if ( version > 0 )
    334     {
    335       OTV_OPTIONAL_OFFSET32( itemVarStore );
    336       OTV_SIZE_CHECK32( itemVarStore );
    337       if ( itemVarStore )
    338         OTV_TRACE(( "  [omitting itemVarStore validation]\n" )); /* XXX */
    339     }
    340 
    341     FT_TRACE4(( "\n" ));
    342   }
    343 
    344 
    345 /* END */
    346