Home | History | Annotate | Download | only in gxvalid
      1 /****************************************************************************
      2  *
      3  * gxvcommn.h
      4  *
      5  *   TrueTypeGX/AAT common tables validation (specification).
      6  *
      7  * Copyright 2004-2018 by
      8  * suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
      9  * David Turner, Robert Wilhelm, and Werner Lemberg.
     10  *
     11  * This file is part of the FreeType project, and may only be used,
     12  * modified, and distributed under the terms of the FreeType project
     13  * license, LICENSE.TXT.  By continuing to use, modify, or distribute
     14  * this file you indicate that you have read the license and
     15  * understand and accept it fully.
     16  *
     17  */
     18 
     19 /****************************************************************************
     20  *
     21  * gxvalid is derived from both gxlayout module and otvalid module.
     22  * Development of gxlayout is supported by the Information-technology
     23  * Promotion Agency(IPA), Japan.
     24  *
     25  */
     26 
     27 
     28   /*
     29    * keywords in variable naming
     30    * ---------------------------
     31    * table:  Of type FT_Bytes, pointing to the start of this table/subtable.
     32    * limit:  Of type FT_Bytes, pointing to the end of this table/subtable,
     33    *         including padding for alignment.
     34    * offset: Of type FT_UInt, the number of octets from the start to target.
     35    * length: Of type FT_UInt, the number of octets from the start to the
     36    *         end in this table/subtable, including padding for alignment.
     37    *
     38    *  _MIN, _MAX: Should be added to the tail of macros, as INT_MIN, etc.
     39    */
     40 
     41 
     42 #ifndef GXVCOMMN_H_
     43 #define GXVCOMMN_H_
     44 
     45 
     46 #include <ft2build.h>
     47 #include "gxvalid.h"
     48 #include FT_INTERNAL_DEBUG_H
     49 #include FT_SFNT_NAMES_H
     50 
     51 
     52 FT_BEGIN_HEADER
     53 
     54 
     55   /* some variables are not evaluated or only used in trace */
     56 
     57 #ifdef  FT_DEBUG_LEVEL_TRACE
     58 #define GXV_LOAD_TRACE_VARS
     59 #else
     60 #undef  GXV_LOAD_TRACE_VARS
     61 #endif
     62 
     63 #undef GXV_LOAD_UNUSED_VARS /* debug purpose */
     64 
     65 #define IS_PARANOID_VALIDATION          ( gxvalid->root->level >= FT_VALIDATE_PARANOID )
     66 #define GXV_SET_ERR_IF_PARANOID( err )  { if ( IS_PARANOID_VALIDATION ) ( err ); }
     67 
     68   /*************************************************************************/
     69   /*************************************************************************/
     70   /*****                                                               *****/
     71   /*****                         VALIDATION                            *****/
     72   /*****                                                               *****/
     73   /*************************************************************************/
     74   /*************************************************************************/
     75 
     76   typedef struct GXV_ValidatorRec_*  GXV_Validator;
     77 
     78 
     79 #define DUMMY_LIMIT 0
     80 
     81   typedef void
     82   (*GXV_Validate_Func)( FT_Bytes       table,
     83                         FT_Bytes       limit,
     84                         GXV_Validator  gxvalid );
     85 
     86 
     87   /* ====================== LookupTable Validator ======================== */
     88 
     89   typedef union  GXV_LookupValueDesc_
     90   {
     91     FT_UShort u;
     92     FT_Short  s;
     93 
     94   } GXV_LookupValueDesc;
     95 
     96   typedef const GXV_LookupValueDesc* GXV_LookupValueCPtr;
     97 
     98   typedef enum  GXV_LookupValue_SignSpec_
     99   {
    100     GXV_LOOKUPVALUE_UNSIGNED = 0,
    101     GXV_LOOKUPVALUE_SIGNED
    102 
    103   } GXV_LookupValue_SignSpec;
    104 
    105 
    106   typedef void
    107   (*GXV_Lookup_Value_Validate_Func)( FT_UShort            glyph,
    108                                      GXV_LookupValueCPtr  value_p,
    109                                      GXV_Validator        gxvalid );
    110 
    111   typedef GXV_LookupValueDesc
    112   (*GXV_Lookup_Fmt4_Transit_Func)( FT_UShort            relative_gindex,
    113                                    GXV_LookupValueCPtr  base_value_p,
    114                                    FT_Bytes             lookuptbl_limit,
    115                                    GXV_Validator        gxvalid );
    116 
    117 
    118   /* ====================== StateTable Validator ========================= */
    119 
    120   typedef enum  GXV_GlyphOffset_Format_
    121   {
    122     GXV_GLYPHOFFSET_NONE   = -1,
    123     GXV_GLYPHOFFSET_UCHAR  = 2,
    124     GXV_GLYPHOFFSET_CHAR,
    125     GXV_GLYPHOFFSET_USHORT = 4,
    126     GXV_GLYPHOFFSET_SHORT,
    127     GXV_GLYPHOFFSET_ULONG  = 8,
    128     GXV_GLYPHOFFSET_LONG
    129 
    130   } GXV_GlyphOffset_Format;
    131 
    132 
    133 #define GXV_GLYPHOFFSET_FMT( table )           \
    134         ( gxvalid->table.entry_glyphoffset_fmt )
    135 
    136 #define GXV_GLYPHOFFSET_SIZE( table )              \
    137         ( gxvalid->table.entry_glyphoffset_fmt / 2 )
    138 
    139 
    140   /* ----------------------- 16bit StateTable ---------------------------- */
    141 
    142   typedef union  GXV_StateTable_GlyphOffsetDesc_
    143   {
    144     FT_Byte    uc;
    145     FT_UShort  u;       /* same as GXV_LookupValueDesc */
    146     FT_ULong   ul;
    147     FT_Char    c;
    148     FT_Short   s;       /* same as GXV_LookupValueDesc */
    149     FT_Long    l;
    150 
    151   } GXV_StateTable_GlyphOffsetDesc;
    152 
    153   typedef const GXV_StateTable_GlyphOffsetDesc* GXV_StateTable_GlyphOffsetCPtr;
    154 
    155   typedef void
    156   (*GXV_StateTable_Subtable_Setup_Func)( FT_UShort      table_size,
    157                                          FT_UShort      classTable,
    158                                          FT_UShort      stateArray,
    159                                          FT_UShort      entryTable,
    160                                          FT_UShort*     classTable_length_p,
    161                                          FT_UShort*     stateArray_length_p,
    162                                          FT_UShort*     entryTable_length_p,
    163                                          GXV_Validator  gxvalid );
    164 
    165   typedef void
    166   (*GXV_StateTable_Entry_Validate_Func)(
    167      FT_Byte                         state,
    168      FT_UShort                       flags,
    169      GXV_StateTable_GlyphOffsetCPtr  glyphOffset_p,
    170      FT_Bytes                        statetable_table,
    171      FT_Bytes                        statetable_limit,
    172      GXV_Validator                   gxvalid );
    173 
    174   typedef void
    175   (*GXV_StateTable_OptData_Load_Func)( FT_Bytes       table,
    176                                        FT_Bytes       limit,
    177                                        GXV_Validator  gxvalid );
    178 
    179   typedef struct  GXV_StateTable_ValidatorRec_
    180   {
    181     GXV_GlyphOffset_Format              entry_glyphoffset_fmt;
    182     void*                               optdata;
    183 
    184     GXV_StateTable_Subtable_Setup_Func  subtable_setup_func;
    185     GXV_StateTable_Entry_Validate_Func  entry_validate_func;
    186     GXV_StateTable_OptData_Load_Func    optdata_load_func;
    187 
    188   } GXV_StateTable_ValidatorRec, *GXV_StateTable_ValidatorRecData;
    189 
    190 
    191   /* ---------------------- 32bit XStateTable ---------------------------- */
    192 
    193   typedef GXV_StateTable_GlyphOffsetDesc  GXV_XStateTable_GlyphOffsetDesc;
    194 
    195   typedef const GXV_XStateTable_GlyphOffsetDesc* GXV_XStateTable_GlyphOffsetCPtr;
    196 
    197   typedef void
    198   (*GXV_XStateTable_Subtable_Setup_Func)( FT_ULong       table_size,
    199                                           FT_ULong       classTable,
    200                                           FT_ULong       stateArray,
    201                                           FT_ULong       entryTable,
    202                                           FT_ULong*      classTable_length_p,
    203                                           FT_ULong*      stateArray_length_p,
    204                                           FT_ULong*      entryTable_length_p,
    205                                           GXV_Validator  gxvalid );
    206 
    207   typedef void
    208   (*GXV_XStateTable_Entry_Validate_Func)(
    209      FT_UShort                       state,
    210      FT_UShort                       flags,
    211      GXV_StateTable_GlyphOffsetCPtr  glyphOffset_p,
    212      FT_Bytes                        xstatetable_table,
    213      FT_Bytes                        xstatetable_limit,
    214      GXV_Validator                   gxvalid );
    215 
    216 
    217   typedef GXV_StateTable_OptData_Load_Func  GXV_XStateTable_OptData_Load_Func;
    218 
    219 
    220   typedef struct  GXV_XStateTable_ValidatorRec_
    221   {
    222     int                                  entry_glyphoffset_fmt;
    223     void*                                optdata;
    224 
    225     GXV_XStateTable_Subtable_Setup_Func  subtable_setup_func;
    226     GXV_XStateTable_Entry_Validate_Func  entry_validate_func;
    227     GXV_XStateTable_OptData_Load_Func    optdata_load_func;
    228 
    229     FT_ULong                             nClasses;
    230     FT_UShort                            maxClassID;
    231 
    232   } GXV_XStateTable_ValidatorRec, *GXV_XStateTable_ValidatorRecData;
    233 
    234 
    235   /* ===================================================================== */
    236 
    237   typedef struct  GXV_ValidatorRec_
    238   {
    239     FT_Validator  root;
    240 
    241     FT_Face       face;
    242     void*         table_data;
    243 
    244     FT_ULong      subtable_length;
    245 
    246     GXV_LookupValue_SignSpec        lookupval_sign;
    247     GXV_Lookup_Value_Validate_Func  lookupval_func;
    248     GXV_Lookup_Fmt4_Transit_Func    lookupfmt4_trans;
    249     FT_Bytes                        lookuptbl_head;
    250 
    251     FT_UShort  min_gid;
    252     FT_UShort  max_gid;
    253 
    254     GXV_StateTable_ValidatorRec     statetable;
    255     GXV_XStateTable_ValidatorRec    xstatetable;
    256 
    257 #ifdef FT_DEBUG_LEVEL_TRACE
    258     FT_UInt             debug_indent;
    259     const FT_String*    debug_function_name[3];
    260 #endif
    261 
    262   } GXV_ValidatorRec;
    263 
    264 
    265 #define GXV_TABLE_DATA( tag, field )                           \
    266         ( ( (GXV_ ## tag ## _Data)gxvalid->table_data )->field )
    267 
    268 #undef  FT_INVALID_
    269 #define FT_INVALID_( _error ) \
    270           ft_validator_error( gxvalid->root, FT_THROW( _error ) )
    271 
    272 #define GXV_LIMIT_CHECK( _count )                                     \
    273           FT_BEGIN_STMNT                                              \
    274             if ( p + _count > ( limit? limit : gxvalid->root->limit ) ) \
    275               FT_INVALID_TOO_SHORT;                                   \
    276           FT_END_STMNT
    277 
    278 
    279 #ifdef FT_DEBUG_LEVEL_TRACE
    280 
    281 #define GXV_INIT  gxvalid->debug_indent = 0
    282 
    283 #define GXV_NAME_ENTER( name )                             \
    284           FT_BEGIN_STMNT                                   \
    285             gxvalid->debug_indent += 2;                      \
    286             FT_TRACE4(( "%*.s", gxvalid->debug_indent, 0 )); \
    287             FT_TRACE4(( "%s table\n", name ));             \
    288           FT_END_STMNT
    289 
    290 #define GXV_EXIT  gxvalid->debug_indent -= 2
    291 
    292 #define GXV_TRACE( s )                                     \
    293           FT_BEGIN_STMNT                                   \
    294             FT_TRACE4(( "%*.s", gxvalid->debug_indent, 0 )); \
    295             FT_TRACE4( s );                                \
    296           FT_END_STMNT
    297 
    298 #else /* !FT_DEBUG_LEVEL_TRACE */
    299 
    300 #define GXV_INIT                do { } while ( 0 )
    301 #define GXV_NAME_ENTER( name )  do { } while ( 0 )
    302 #define GXV_EXIT                do { } while ( 0 )
    303 
    304 #define GXV_TRACE( s )          do { } while ( 0 )
    305 
    306 #endif  /* !FT_DEBUG_LEVEL_TRACE */
    307 
    308 
    309   /*************************************************************************/
    310   /*************************************************************************/
    311   /*****                                                               *****/
    312   /*****                    32bit alignment checking                   *****/
    313   /*****                                                               *****/
    314   /*************************************************************************/
    315   /*************************************************************************/
    316 
    317 #define GXV_32BIT_ALIGNMENT_VALIDATE( a ) \
    318           FT_BEGIN_STMNT                  \
    319             {                             \
    320               if ( (a) & 3 )              \
    321                 FT_INVALID_OFFSET;        \
    322             }                             \
    323           FT_END_STMNT
    324 
    325 
    326   /*************************************************************************/
    327   /*************************************************************************/
    328   /*****                                                               *****/
    329   /*****                    Dumping Binary Data                        *****/
    330   /*****                                                               *****/
    331   /*************************************************************************/
    332   /*************************************************************************/
    333 
    334 #define GXV_TRACE_HEXDUMP( p, len )                     \
    335           FT_BEGIN_STMNT                                \
    336             {                                           \
    337               FT_Bytes  b;                              \
    338                                                         \
    339                                                         \
    340               for ( b = p; b < (FT_Bytes)p + len; b++ ) \
    341                 FT_TRACE1(("\\x%02x", *b));             \
    342             }                                           \
    343           FT_END_STMNT
    344 
    345 #define GXV_TRACE_HEXDUMP_C( p, len )                   \
    346           FT_BEGIN_STMNT                                \
    347             {                                           \
    348               FT_Bytes  b;                              \
    349                                                         \
    350                                                         \
    351               for ( b = p; b < (FT_Bytes)p + len; b++ ) \
    352                 if ( 0x40 < *b && *b < 0x7E )           \
    353                   FT_TRACE1(("%c", *b));                \
    354                 else                                    \
    355                   FT_TRACE1(("\\x%02x", *b));           \
    356             }                                           \
    357           FT_END_STMNT
    358 
    359 #define GXV_TRACE_HEXDUMP_SFNTNAME( n )               \
    360           GXV_TRACE_HEXDUMP( n.string, n.string_len )
    361 
    362 
    363   /*************************************************************************/
    364   /*************************************************************************/
    365   /*****                                                               *****/
    366   /*****                         LOOKUP TABLE                          *****/
    367   /*****                                                               *****/
    368   /*************************************************************************/
    369   /*************************************************************************/
    370 
    371   FT_LOCAL( void )
    372   gxv_BinSrchHeader_validate( FT_Bytes       p,
    373                               FT_Bytes       limit,
    374                               FT_UShort*     unitSize_p,
    375                               FT_UShort*     nUnits_p,
    376                               GXV_Validator  gxvalid );
    377 
    378   FT_LOCAL( void )
    379   gxv_LookupTable_validate( FT_Bytes       table,
    380                             FT_Bytes       limit,
    381                             GXV_Validator  gxvalid );
    382 
    383 
    384   /*************************************************************************/
    385   /*************************************************************************/
    386   /*****                                                               *****/
    387   /*****                          Glyph ID                             *****/
    388   /*****                                                               *****/
    389   /*************************************************************************/
    390   /*************************************************************************/
    391 
    392   FT_LOCAL( FT_Int )
    393   gxv_glyphid_validate( FT_UShort      gid,
    394                         GXV_Validator  gxvalid );
    395 
    396 
    397   /*************************************************************************/
    398   /*************************************************************************/
    399   /*****                                                               *****/
    400   /*****                        CONTROL POINT                          *****/
    401   /*****                                                               *****/
    402   /*************************************************************************/
    403   /*************************************************************************/
    404 
    405   FT_LOCAL( void )
    406   gxv_ctlPoint_validate( FT_UShort      gid,
    407                          FT_UShort      ctl_point,
    408                          GXV_Validator  gxvalid );
    409 
    410 
    411   /*************************************************************************/
    412   /*************************************************************************/
    413   /*****                                                               *****/
    414   /*****                          SFNT NAME                            *****/
    415   /*****                                                               *****/
    416   /*************************************************************************/
    417   /*************************************************************************/
    418 
    419   FT_LOCAL( void )
    420   gxv_sfntName_validate( FT_UShort      name_index,
    421                          FT_UShort      min_index,
    422                          FT_UShort      max_index,
    423                          GXV_Validator  gxvalid );
    424 
    425 
    426   /*************************************************************************/
    427   /*************************************************************************/
    428   /*****                                                               *****/
    429   /*****                          STATE TABLE                          *****/
    430   /*****                                                               *****/
    431   /*************************************************************************/
    432   /*************************************************************************/
    433 
    434   FT_LOCAL( void )
    435   gxv_StateTable_subtable_setup( FT_UShort      table_size,
    436                                  FT_UShort      classTable,
    437                                  FT_UShort      stateArray,
    438                                  FT_UShort      entryTable,
    439                                  FT_UShort*     classTable_length_p,
    440                                  FT_UShort*     stateArray_length_p,
    441                                  FT_UShort*     entryTable_length_p,
    442                                  GXV_Validator  gxvalid );
    443 
    444   FT_LOCAL( void )
    445   gxv_XStateTable_subtable_setup( FT_ULong       table_size,
    446                                   FT_ULong       classTable,
    447                                   FT_ULong       stateArray,
    448                                   FT_ULong       entryTable,
    449                                   FT_ULong*      classTable_length_p,
    450                                   FT_ULong*      stateArray_length_p,
    451                                   FT_ULong*      entryTable_length_p,
    452                                   GXV_Validator  gxvalid );
    453 
    454   FT_LOCAL( void )
    455   gxv_StateTable_validate( FT_Bytes       table,
    456                            FT_Bytes       limit,
    457                            GXV_Validator  gxvalid );
    458 
    459   FT_LOCAL( void )
    460   gxv_XStateTable_validate( FT_Bytes       table,
    461                             FT_Bytes       limit,
    462                             GXV_Validator  gxvalid );
    463 
    464 
    465   /*************************************************************************/
    466   /*************************************************************************/
    467   /*****                                                               *****/
    468   /*****                 UTILITY MACROS AND FUNCTIONS                  *****/
    469   /*****                                                               *****/
    470   /*************************************************************************/
    471   /*************************************************************************/
    472 
    473   FT_LOCAL( void )
    474   gxv_array_getlimits_byte( FT_Bytes       table,
    475                             FT_Bytes       limit,
    476                             FT_Byte*       min,
    477                             FT_Byte*       max,
    478                             GXV_Validator  gxvalid );
    479 
    480   FT_LOCAL( void )
    481   gxv_array_getlimits_ushort( FT_Bytes       table,
    482                               FT_Bytes       limit,
    483                               FT_UShort*     min,
    484                               FT_UShort*     max,
    485                               GXV_Validator  gxvalid );
    486 
    487   FT_LOCAL( void )
    488   gxv_set_length_by_ushort_offset( FT_UShort*     offset,
    489                                    FT_UShort**    length,
    490                                    FT_UShort*     buff,
    491                                    FT_UInt        nmemb,
    492                                    FT_UShort      limit,
    493                                    GXV_Validator  gxvalid );
    494 
    495   FT_LOCAL( void )
    496   gxv_set_length_by_ulong_offset( FT_ULong*      offset,
    497                                   FT_ULong**     length,
    498                                   FT_ULong*      buff,
    499                                   FT_UInt        nmemb,
    500                                   FT_ULong       limit,
    501                                   GXV_Validator  gxvalid);
    502 
    503 
    504 #define GXV_SUBTABLE_OFFSET_CHECK( _offset )          \
    505           FT_BEGIN_STMNT                              \
    506             if ( (_offset) > gxvalid->subtable_length ) \
    507               FT_INVALID_OFFSET;                      \
    508           FT_END_STMNT
    509 
    510 #define GXV_SUBTABLE_LIMIT_CHECK( _count )                  \
    511           FT_BEGIN_STMNT                                    \
    512             if ( ( p + (_count) - gxvalid->subtable_start ) > \
    513                    gxvalid->subtable_length )                 \
    514               FT_INVALID_TOO_SHORT;                         \
    515           FT_END_STMNT
    516 
    517 #define GXV_USHORT_TO_SHORT( _us )                                    \
    518           ( ( 0x8000U < ( _us ) ) ? ( ( _us ) - 0x8000U ) : ( _us ) )
    519 
    520 #define GXV_STATETABLE_HEADER_SIZE  ( 2 + 2 + 2 + 2 )
    521 #define GXV_STATEHEADER_SIZE        GXV_STATETABLE_HEADER_SIZE
    522 
    523 #define GXV_XSTATETABLE_HEADER_SIZE  ( 4 + 4 + 4 + 4 )
    524 #define GXV_XSTATEHEADER_SIZE        GXV_XSTATETABLE_HEADER_SIZE
    525 
    526 
    527   /*************************************************************************/
    528   /*************************************************************************/
    529   /*****                                                               *****/
    530   /*****                        Table overlapping                      *****/
    531   /*****                                                               *****/
    532   /*************************************************************************/
    533   /*************************************************************************/
    534 
    535   typedef struct  GXV_odtect_DataRec_
    536   {
    537     FT_Bytes    start;
    538     FT_ULong    length;
    539     FT_String*  name;
    540 
    541   } GXV_odtect_DataRec,  *GXV_odtect_Data;
    542 
    543   typedef struct  GXV_odtect_RangeRec_
    544   {
    545     FT_UInt          nRanges;
    546     GXV_odtect_Data  range;
    547 
    548   } GXV_odtect_RangeRec, *GXV_odtect_Range;
    549 
    550 
    551   FT_LOCAL( void )
    552   gxv_odtect_add_range( FT_Bytes          start,
    553                         FT_ULong          length,
    554                         const FT_String*  name,
    555                         GXV_odtect_Range  odtect );
    556 
    557   FT_LOCAL( void )
    558   gxv_odtect_validate( GXV_odtect_Range  odtect,
    559                        GXV_Validator     gxvalid );
    560 
    561 
    562 #define GXV_ODTECT( n, odtect )                              \
    563           GXV_odtect_DataRec   odtect ## _range[n];          \
    564           GXV_odtect_RangeRec  odtect ## _rec = { 0, NULL }; \
    565           GXV_odtect_Range     odtect = NULL
    566 
    567 #define GXV_ODTECT_INIT( odtect )                      \
    568           FT_BEGIN_STMNT                               \
    569             odtect ## _rec.nRanges = 0;                \
    570             odtect ## _rec.range   = odtect ## _range; \
    571             odtect                 = & odtect ## _rec; \
    572           FT_END_STMNT
    573 
    574 
    575  /* */
    576 
    577 FT_END_HEADER
    578 
    579 #endif /* GXVCOMMN_H_ */
    580 
    581 
    582 /* END */
    583