Home | History | Annotate | Download | only in otvalid
      1 /***************************************************************************/
      2 /*                                                                         */
      3 /*  otvjstf.c                                                              */
      4 /*                                                                         */
      5 /*    OpenType JSTF 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 #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  trace_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 = %d)\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 = %d)\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 */
    260