tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

otvbase.c (7882B)


      1 /****************************************************************************
      2 *
      3 * otvbase.c
      4 *
      5 *   OpenType BASE table validation (body).
      6 *
      7 * Copyright (C) 2004-2025 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  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 %u)\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 = %u)\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 = %u)\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 = %u)\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 = %u)\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 = %u)\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 */