tor-browser

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

otvjstf.c (7126B)


      1 /****************************************************************************
      2 *
      3 * otvjstf.c
      4 *
      5 *   OpenType JSTF 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 #include "otvgpos.h"
     22 
     23 
     24  /**************************************************************************
     25   *
     26   * The macro FT_COMPONENT is used in trace mode.  It is an implicit
     27   * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
     28   * messages during execution.
     29   */
     30 #undef  FT_COMPONENT
     31 #define FT_COMPONENT  otvjstf
     32 
     33 
     34 #define JstfPriorityFunc  otv_JstfPriority_validate
     35 #define JstfLookupFunc    otv_GPOS_subtable_validate
     36 
     37  /* uses otvalid->extra1 (GSUB lookup count) */
     38  /* uses otvalid->extra2 (GPOS lookup count) */
     39  /* sets otvalid->extra1 (counter)           */
     40 
     41  static void
     42  otv_JstfPriority_validate( FT_Bytes       table,
     43                             OTV_Validator  otvalid )
     44  {
     45    FT_Bytes  p = table;
     46    FT_UInt   table_size;
     47    FT_UInt   gsub_lookup_count, gpos_lookup_count;
     48 
     49    OTV_OPTIONAL_TABLE( ShrinkageEnableGSUB  );
     50    OTV_OPTIONAL_TABLE( ShrinkageDisableGSUB );
     51    OTV_OPTIONAL_TABLE( ShrinkageEnableGPOS  );
     52    OTV_OPTIONAL_TABLE( ShrinkageDisableGPOS );
     53    OTV_OPTIONAL_TABLE( ExtensionEnableGSUB  );
     54    OTV_OPTIONAL_TABLE( ExtensionDisableGSUB );
     55    OTV_OPTIONAL_TABLE( ExtensionEnableGPOS  );
     56    OTV_OPTIONAL_TABLE( ExtensionDisableGPOS );
     57    OTV_OPTIONAL_TABLE( ShrinkageJstfMax );
     58    OTV_OPTIONAL_TABLE( ExtensionJstfMax );
     59 
     60 
     61    OTV_ENTER;
     62    OTV_TRACE(( "JstfPriority table\n" ));
     63 
     64    OTV_LIMIT_CHECK( 20 );
     65 
     66    gsub_lookup_count = otvalid->extra1;
     67    gpos_lookup_count = otvalid->extra2;
     68 
     69    table_size = 20;
     70 
     71    otvalid->extra1 = gsub_lookup_count;
     72 
     73    OTV_OPTIONAL_OFFSET( ShrinkageEnableGSUB );
     74    OTV_SIZE_CHECK( ShrinkageEnableGSUB );
     75    if ( ShrinkageEnableGSUB )
     76      otv_x_ux( table + ShrinkageEnableGSUB, otvalid );
     77 
     78    OTV_OPTIONAL_OFFSET( ShrinkageDisableGSUB );
     79    OTV_SIZE_CHECK( ShrinkageDisableGSUB );
     80    if ( ShrinkageDisableGSUB )
     81      otv_x_ux( table + ShrinkageDisableGSUB, otvalid );
     82 
     83    otvalid->extra1 = gpos_lookup_count;
     84 
     85    OTV_OPTIONAL_OFFSET( ShrinkageEnableGPOS );
     86    OTV_SIZE_CHECK( ShrinkageEnableGPOS );
     87    if ( ShrinkageEnableGPOS )
     88      otv_x_ux( table + ShrinkageEnableGPOS, otvalid );
     89 
     90    OTV_OPTIONAL_OFFSET( ShrinkageDisableGPOS );
     91    OTV_SIZE_CHECK( ShrinkageDisableGPOS );
     92    if ( ShrinkageDisableGPOS )
     93      otv_x_ux( table + ShrinkageDisableGPOS, otvalid );
     94 
     95    OTV_OPTIONAL_OFFSET( ShrinkageJstfMax );
     96    OTV_SIZE_CHECK( ShrinkageJstfMax );
     97    if ( ShrinkageJstfMax )
     98    {
     99      /* XXX: check lookup types? */
    100      OTV_NEST2( JstfMax, JstfLookup );
    101      OTV_RUN( table + ShrinkageJstfMax, otvalid );
    102    }
    103 
    104    otvalid->extra1 = gsub_lookup_count;
    105 
    106    OTV_OPTIONAL_OFFSET( ExtensionEnableGSUB );
    107    OTV_SIZE_CHECK( ExtensionEnableGSUB );
    108    if ( ExtensionEnableGSUB )
    109      otv_x_ux( table + ExtensionEnableGSUB, otvalid );
    110 
    111    OTV_OPTIONAL_OFFSET( ExtensionDisableGSUB );
    112    OTV_SIZE_CHECK( ExtensionDisableGSUB );
    113    if ( ExtensionDisableGSUB )
    114      otv_x_ux( table + ExtensionDisableGSUB, otvalid );
    115 
    116    otvalid->extra1 = gpos_lookup_count;
    117 
    118    OTV_OPTIONAL_OFFSET( ExtensionEnableGPOS );
    119    OTV_SIZE_CHECK( ExtensionEnableGPOS );
    120    if ( ExtensionEnableGPOS )
    121      otv_x_ux( table + ExtensionEnableGPOS, otvalid );
    122 
    123    OTV_OPTIONAL_OFFSET( ExtensionDisableGPOS );
    124    OTV_SIZE_CHECK( ExtensionDisableGPOS );
    125    if ( ExtensionDisableGPOS )
    126      otv_x_ux( table + ExtensionDisableGPOS, otvalid );
    127 
    128    OTV_OPTIONAL_OFFSET( ExtensionJstfMax );
    129    OTV_SIZE_CHECK( ExtensionJstfMax );
    130    if ( ExtensionJstfMax )
    131    {
    132      /* XXX: check lookup types? */
    133      OTV_NEST2( JstfMax, JstfLookup );
    134      OTV_RUN( table + ExtensionJstfMax, otvalid );
    135    }
    136 
    137    otvalid->extra1 = gsub_lookup_count;
    138    otvalid->extra2 = gpos_lookup_count;
    139 
    140    OTV_EXIT;
    141  }
    142 
    143 
    144  /* sets otvalid->extra (glyph count)               */
    145  /* sets otvalid->func1 (otv_JstfPriority_validate) */
    146 
    147  static void
    148  otv_JstfScript_validate( FT_Bytes       table,
    149                           OTV_Validator  otvalid )
    150  {
    151    FT_Bytes  p = table;
    152    FT_UInt   table_size;
    153    FT_UInt   JstfLangSysCount;
    154 
    155    OTV_OPTIONAL_TABLE( ExtGlyph );
    156    OTV_OPTIONAL_TABLE( DefJstfLangSys );
    157 
    158 
    159    OTV_NAME_ENTER( "JstfScript" );
    160 
    161    OTV_LIMIT_CHECK( 6 );
    162    OTV_OPTIONAL_OFFSET( ExtGlyph );
    163    OTV_OPTIONAL_OFFSET( DefJstfLangSys );
    164    JstfLangSysCount = FT_NEXT_USHORT( p );
    165 
    166    OTV_TRACE(( " (JstfLangSysCount = %u)\n", JstfLangSysCount ));
    167 
    168    table_size = JstfLangSysCount * 6 + 6;
    169 
    170    OTV_SIZE_CHECK( ExtGlyph );
    171    if ( ExtGlyph )
    172    {
    173      otvalid->extra1 = otvalid->glyph_count;
    174      OTV_NEST1( ExtenderGlyph );
    175      OTV_RUN( table + ExtGlyph, otvalid );
    176    }
    177 
    178    OTV_SIZE_CHECK( DefJstfLangSys );
    179    if ( DefJstfLangSys )
    180    {
    181      OTV_NEST2( JstfLangSys, JstfPriority );
    182      OTV_RUN( table + DefJstfLangSys, otvalid );
    183    }
    184 
    185    OTV_LIMIT_CHECK( 6 * JstfLangSysCount );
    186 
    187    /* JstfLangSysRecord */
    188    OTV_NEST2( JstfLangSys, JstfPriority );
    189    for ( ; JstfLangSysCount > 0; JstfLangSysCount-- )
    190    {
    191      p += 4;       /* skip JstfLangSysTag */
    192 
    193      OTV_RUN( table + FT_NEXT_USHORT( p ), otvalid );
    194    }
    195 
    196    OTV_EXIT;
    197  }
    198 
    199 
    200  /* sets otvalid->extra1 (GSUB lookup count) */
    201  /* sets otvalid->extra2 (GPOS lookup count) */
    202  /* sets otvalid->glyph_count                */
    203 
    204  FT_LOCAL_DEF( void )
    205  otv_JSTF_validate( FT_Bytes      table,
    206                     FT_Bytes      gsub,
    207                     FT_Bytes      gpos,
    208                     FT_UInt       glyph_count,
    209                     FT_Validator  ftvalid )
    210  {
    211    OTV_ValidatorRec  otvalidrec;
    212    OTV_Validator     otvalid = &otvalidrec;
    213    FT_Bytes          p     = table;
    214    FT_UInt           JstfScriptCount;
    215 
    216 
    217    otvalid->root = ftvalid;
    218 
    219 
    220    FT_TRACE3(( "validating JSTF table\n" ));
    221    OTV_INIT;
    222 
    223    OTV_LIMIT_CHECK( 6 );
    224 
    225    if ( FT_NEXT_ULONG( p ) != 0x10000UL )      /* Version */
    226      FT_INVALID_FORMAT;
    227 
    228    JstfScriptCount = FT_NEXT_USHORT( p );
    229 
    230    FT_TRACE3(( " (JstfScriptCount = %u)\n", JstfScriptCount ));
    231 
    232    OTV_LIMIT_CHECK( JstfScriptCount * 6 );
    233 
    234    if ( gsub )
    235      otvalid->extra1 = otv_GSUBGPOS_get_Lookup_count( gsub );
    236    else
    237      otvalid->extra1 = 0;
    238 
    239    if ( gpos )
    240      otvalid->extra2 = otv_GSUBGPOS_get_Lookup_count( gpos );
    241    else
    242      otvalid->extra2 = 0;
    243 
    244    otvalid->glyph_count = glyph_count;
    245 
    246    /* JstfScriptRecord */
    247    for ( ; JstfScriptCount > 0; JstfScriptCount-- )
    248    {
    249      p += 4;       /* skip JstfScriptTag */
    250 
    251      /* JstfScript */
    252      otv_JstfScript_validate( table + FT_NEXT_USHORT( p ), otvalid );
    253    }
    254 
    255    FT_TRACE4(( "\n" ));
    256  }
    257 
    258 
    259 /* END */