misc/libfreetype/src/otvalid/otvbase.c
changeset 9431 0f5961910e27
parent 9357 a501f5ec7b34
parent 9429 7a97a554ac80
child 9433 f0a8ac191839
equal deleted inserted replaced
9357:a501f5ec7b34 9431:0f5961910e27
     1 /***************************************************************************/
       
     2 /*                                                                         */
       
     3 /*  otvbase.c                                                              */
       
     4 /*                                                                         */
       
     5 /*    OpenType BASE table validation (body).                               */
       
     6 /*                                                                         */
       
     7 /*  Copyright 2004, 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 "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  valid )
       
    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 ), valid );
       
    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  valid )
       
    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  valid )
       
    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 ), valid );
       
   116 
       
   117     OTV_EXIT;
       
   118   }
       
   119 
       
   120 
       
   121   static void
       
   122   otv_MinMax_validate( FT_Bytes       table,
       
   123                        OTV_Validator  valid )
       
   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, valid );
       
   148 
       
   149     OTV_SIZE_CHECK( MaxCoord );
       
   150     if ( MaxCoord )
       
   151       otv_BaseCoord_validate( table + MaxCoord, valid );
       
   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, valid );
       
   166 
       
   167       OTV_SIZE_CHECK( MaxCoord );
       
   168       if ( MaxCoord )
       
   169         otv_BaseCoord_validate( table + MaxCoord, valid );
       
   170     }
       
   171 
       
   172     OTV_EXIT;
       
   173   }
       
   174 
       
   175 
       
   176   static void
       
   177   otv_BaseScript_validate( FT_Bytes       table,
       
   178                            OTV_Validator  valid )
       
   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, valid );
       
   202 
       
   203     OTV_SIZE_CHECK( DefaultMinMax );
       
   204     if ( DefaultMinMax )
       
   205       otv_MinMax_validate( table + DefaultMinMax, valid );
       
   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 ), valid );
       
   215     }
       
   216 
       
   217     OTV_EXIT;
       
   218   }
       
   219 
       
   220 
       
   221   static void
       
   222   otv_BaseScriptList_validate( FT_Bytes       table,
       
   223                                OTV_Validator  valid )
       
   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 ), valid );
       
   245     }
       
   246 
       
   247     OTV_EXIT;
       
   248   }
       
   249 
       
   250 
       
   251   static void
       
   252   otv_Axis_validate( FT_Bytes       table,
       
   253                      OTV_Validator  valid )
       
   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, valid );
       
   271 
       
   272     /* BaseScriptList */
       
   273     otv_BaseScriptList_validate( table + FT_NEXT_USHORT( p ), valid );
       
   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  validrec;
       
   284     OTV_Validator     valid = &validrec;
       
   285     FT_Bytes          p     = table;
       
   286     FT_UInt           table_size;
       
   287 
       
   288     OTV_OPTIONAL_TABLE( HorizAxis );
       
   289     OTV_OPTIONAL_TABLE( VertAxis  );
       
   290 
       
   291 
       
   292     valid->root = ftvalid;
       
   293 
       
   294     FT_TRACE3(( "validating BASE table\n" ));
       
   295     OTV_INIT;
       
   296 
       
   297     OTV_LIMIT_CHECK( 6 );
       
   298 
       
   299     if ( FT_NEXT_ULONG( p ) != 0x10000UL )      /* Version */
       
   300       FT_INVALID_FORMAT;
       
   301 
       
   302     table_size = 6;
       
   303 
       
   304     OTV_OPTIONAL_OFFSET( HorizAxis );
       
   305     OTV_SIZE_CHECK( HorizAxis );
       
   306     if ( HorizAxis )
       
   307       otv_Axis_validate( table + HorizAxis, valid );
       
   308 
       
   309     OTV_OPTIONAL_OFFSET( VertAxis );
       
   310     OTV_SIZE_CHECK( VertAxis );
       
   311     if ( VertAxis )
       
   312       otv_Axis_validate( table + VertAxis, valid );
       
   313 
       
   314     FT_TRACE4(( "\n" ));
       
   315   }
       
   316 
       
   317 
       
   318 /* END */