tor-browser

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

otvgdef.c (8882B)


      1 /****************************************************************************
      2 *
      3 * otvgdef.c
      4 *
      5 *   OpenType GDEF 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  otvgdef
     31 
     32 
     33  /*************************************************************************/
     34  /*************************************************************************/
     35  /*****                                                               *****/
     36  /*****                      UTILITY FUNCTIONS                        *****/
     37  /*****                                                               *****/
     38  /*************************************************************************/
     39  /*************************************************************************/
     40 
     41 #define AttachListFunc    otv_O_x_Ox
     42 #define LigCaretListFunc  otv_O_x_Ox
     43 
     44  /* sets valid->extra1 (0)           */
     45 
     46  static void
     47  otv_O_x_Ox( FT_Bytes       table,
     48              OTV_Validator  otvalid )
     49  {
     50    FT_Bytes           p = table;
     51    FT_Bytes           Coverage;
     52    FT_UInt            GlyphCount;
     53    OTV_Validate_Func  func;
     54 
     55 
     56    OTV_ENTER;
     57 
     58    OTV_LIMIT_CHECK( 4 );
     59    Coverage   = table + FT_NEXT_USHORT( p );
     60    GlyphCount = FT_NEXT_USHORT( p );
     61 
     62    OTV_TRACE(( " (GlyphCount = %u)\n", GlyphCount ));
     63 
     64    otv_Coverage_validate( Coverage, otvalid, (FT_Int)GlyphCount );
     65    if ( GlyphCount != otv_Coverage_get_count( Coverage ) )
     66      FT_INVALID_DATA;
     67 
     68    OTV_LIMIT_CHECK( GlyphCount * 2 );
     69 
     70    otvalid->nesting_level++;
     71    func            = otvalid->func[otvalid->nesting_level];
     72    otvalid->extra1 = 0;
     73 
     74    for ( ; GlyphCount > 0; GlyphCount-- )
     75      func( table + FT_NEXT_USHORT( p ), otvalid );
     76 
     77    otvalid->nesting_level--;
     78 
     79    OTV_EXIT;
     80  }
     81 
     82 
     83  /*************************************************************************/
     84  /*************************************************************************/
     85  /*****                                                               *****/
     86  /*****                       LIGATURE CARETS                         *****/
     87  /*****                                                               *****/
     88  /*************************************************************************/
     89  /*************************************************************************/
     90 
     91 #define CaretValueFunc  otv_CaretValue_validate
     92 
     93  static void
     94  otv_CaretValue_validate( FT_Bytes       table,
     95                           OTV_Validator  otvalid )
     96  {
     97    FT_Bytes  p = table;
     98    FT_UInt   CaretValueFormat;
     99 
    100 
    101    OTV_ENTER;
    102 
    103    OTV_LIMIT_CHECK( 4 );
    104 
    105    CaretValueFormat = FT_NEXT_USHORT( p );
    106 
    107    OTV_TRACE(( " (format = %u)\n", CaretValueFormat ));
    108 
    109    switch ( CaretValueFormat )
    110    {
    111    case 1:     /* CaretValueFormat1 */
    112      /* skip Coordinate, no test */
    113      break;
    114 
    115    case 2:     /* CaretValueFormat2 */
    116      /* skip CaretValuePoint, no test */
    117      break;
    118 
    119    case 3:     /* CaretValueFormat3 */
    120      p += 2;   /* skip Coordinate */
    121 
    122      OTV_LIMIT_CHECK( 2 );
    123 
    124      /* DeviceTable */
    125      otv_Device_validate( table + FT_NEXT_USHORT( p ), otvalid );
    126      break;
    127 
    128    default:
    129      FT_INVALID_FORMAT;
    130    }
    131 
    132    OTV_EXIT;
    133  }
    134 
    135 
    136  /*************************************************************************/
    137  /*************************************************************************/
    138  /*****                                                               *****/
    139  /*****                       MARK GLYPH SETS                         *****/
    140  /*****                                                               *****/
    141  /*************************************************************************/
    142  /*************************************************************************/
    143 
    144  static void
    145  otv_MarkGlyphSets_validate( FT_Bytes       table,
    146                              OTV_Validator  otvalid )
    147  {
    148    FT_Bytes  p = table;
    149    FT_UInt   MarkGlyphSetCount;
    150 
    151 
    152    OTV_NAME_ENTER( "MarkGlyphSets" );
    153 
    154    p += 2;     /* skip Format */
    155 
    156    OTV_LIMIT_CHECK( 2 );
    157    MarkGlyphSetCount = FT_NEXT_USHORT( p );
    158 
    159    OTV_TRACE(( " (MarkGlyphSetCount = %u)\n", MarkGlyphSetCount ));
    160 
    161    OTV_LIMIT_CHECK( MarkGlyphSetCount * 4 );      /* CoverageOffsets */
    162 
    163    for ( ; MarkGlyphSetCount > 0; MarkGlyphSetCount-- )
    164      otv_Coverage_validate( table + FT_NEXT_ULONG( p ), otvalid, -1 );
    165 
    166    OTV_EXIT;
    167  }
    168 
    169 
    170  /*************************************************************************/
    171  /*************************************************************************/
    172  /*****                                                               *****/
    173  /*****                         GDEF TABLE                            *****/
    174  /*****                                                               *****/
    175  /*************************************************************************/
    176  /*************************************************************************/
    177 
    178  /* sets otvalid->glyph_count */
    179 
    180  FT_LOCAL_DEF( void )
    181  otv_GDEF_validate( FT_Bytes      table,
    182                     FT_Bytes      gsub,
    183                     FT_Bytes      gpos,
    184                     FT_UInt       glyph_count,
    185                     FT_Validator  ftvalid )
    186  {
    187    OTV_ValidatorRec  otvalidrec;
    188    OTV_Validator     otvalid = &otvalidrec;
    189    FT_Bytes          p       = table;
    190    FT_UInt           table_size;
    191    FT_UShort         version;
    192    FT_Bool           need_MarkAttachClassDef = 1;
    193 
    194    OTV_OPTIONAL_TABLE( GlyphClassDef );
    195    OTV_OPTIONAL_TABLE( AttachListOffset );
    196    OTV_OPTIONAL_TABLE( LigCaretListOffset );
    197    OTV_OPTIONAL_TABLE( MarkAttachClassDef );
    198    OTV_OPTIONAL_TABLE( MarkGlyphSetsDef );
    199 
    200    OTV_OPTIONAL_TABLE32( itemVarStore );
    201 
    202 
    203    otvalid->root = ftvalid;
    204 
    205    FT_TRACE3(( "validating GDEF table\n" ));
    206    OTV_INIT;
    207 
    208    OTV_LIMIT_CHECK( 4 );
    209 
    210    if ( FT_NEXT_USHORT( p ) != 1 )  /* majorVersion */
    211      FT_INVALID_FORMAT;
    212 
    213    version = FT_NEXT_USHORT( p );   /* minorVersion */
    214 
    215    table_size = 10;
    216    switch ( version )
    217    {
    218    case 0:
    219      /* MarkAttachClassDef has been added to the OpenType */
    220      /* specification without increasing GDEF's version,  */
    221      /* so we use this ugly hack to find out whether the  */
    222      /* table is needed actually.                         */
    223 
    224      need_MarkAttachClassDef = FT_BOOL(
    225        otv_GSUBGPOS_have_MarkAttachmentType_flag( gsub ) ||
    226        otv_GSUBGPOS_have_MarkAttachmentType_flag( gpos ) );
    227 
    228      if ( need_MarkAttachClassDef )
    229      {
    230        OTV_LIMIT_CHECK( 8 );
    231        table_size += 2;
    232      }
    233      else
    234        OTV_LIMIT_CHECK( 6 );  /* OpenType < 1.2 */
    235 
    236      break;
    237 
    238    case 2:
    239      OTV_LIMIT_CHECK( 10 );
    240      table_size += 4;
    241      break;
    242 
    243    case 3:
    244      OTV_LIMIT_CHECK( 14 );
    245      table_size += 8;
    246      break;
    247 
    248    default:
    249      FT_INVALID_FORMAT;
    250    }
    251 
    252    otvalid->glyph_count = glyph_count;
    253 
    254    OTV_OPTIONAL_OFFSET( GlyphClassDef );
    255    OTV_SIZE_CHECK( GlyphClassDef );
    256    if ( GlyphClassDef )
    257      otv_ClassDef_validate( table + GlyphClassDef, otvalid );
    258 
    259    OTV_OPTIONAL_OFFSET( AttachListOffset );
    260    OTV_SIZE_CHECK( AttachListOffset );
    261    if ( AttachListOffset )
    262    {
    263      OTV_NEST2( AttachList, AttachPoint );
    264      OTV_RUN( table + AttachListOffset, otvalid );
    265    }
    266 
    267    OTV_OPTIONAL_OFFSET( LigCaretListOffset );
    268    OTV_SIZE_CHECK( LigCaretListOffset );
    269    if ( LigCaretListOffset )
    270    {
    271      OTV_NEST3( LigCaretList, LigGlyph, CaretValue );
    272      OTV_RUN( table + LigCaretListOffset, otvalid );
    273    }
    274 
    275    if ( need_MarkAttachClassDef )
    276    {
    277      OTV_OPTIONAL_OFFSET( MarkAttachClassDef );
    278      OTV_SIZE_CHECK( MarkAttachClassDef );
    279      if ( MarkAttachClassDef )
    280        otv_ClassDef_validate( table + MarkAttachClassDef, otvalid );
    281    }
    282 
    283    if ( version > 0 )
    284    {
    285      OTV_OPTIONAL_OFFSET( MarkGlyphSetsDef );
    286      OTV_SIZE_CHECK( MarkGlyphSetsDef );
    287      if ( MarkGlyphSetsDef )
    288        otv_MarkGlyphSets_validate( table + MarkGlyphSetsDef, otvalid );
    289    }
    290 
    291    if ( version > 2 )
    292    {
    293      OTV_OPTIONAL_OFFSET32( itemVarStore );
    294      OTV_SIZE_CHECK32( itemVarStore );
    295      if ( itemVarStore )
    296        OTV_TRACE(( "  [omitting itemVarStore validation]\n" )); /* XXX */
    297    }
    298 
    299    FT_TRACE4(( "\n" ));
    300  }
    301 
    302 
    303 /* END */