Home | History | Annotate | Download | only in gxvalid
      1 /***************************************************************************/
      2 /*                                                                         */
      3 /*  gxvbsln.c                                                              */
      4 /*                                                                         */
      5 /*    TrueTypeGX/AAT bsln table validation (body).                         */
      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 #include "gxvalid.h"
     29 #include "gxvcommn.h"
     30 
     31 
     32   /*************************************************************************/
     33   /*                                                                       */
     34   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
     35   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
     36   /* messages during execution.                                            */
     37   /*                                                                       */
     38 #undef  FT_COMPONENT
     39 #define FT_COMPONENT  trace_gxvbsln
     40 
     41 
     42   /*************************************************************************/
     43   /*************************************************************************/
     44   /*****                                                               *****/
     45   /*****                      Data and Types                           *****/
     46   /*****                                                               *****/
     47   /*************************************************************************/
     48   /*************************************************************************/
     49 
     50 #define GXV_BSLN_VALUE_COUNT  32
     51 #define GXV_BSLN_VALUE_EMPTY  0xFFFFU
     52 
     53 
     54   typedef struct  GXV_bsln_DataRec_
     55   {
     56     FT_Bytes   ctlPoints_p;
     57     FT_UShort  defaultBaseline;
     58 
     59   } GXV_bsln_DataRec, *GXV_bsln_Data;
     60 
     61 
     62 #define GXV_BSLN_DATA( field )  GXV_TABLE_DATA( bsln, field )
     63 
     64 
     65   /*************************************************************************/
     66   /*************************************************************************/
     67   /*****                                                               *****/
     68   /*****                      UTILITY FUNCTIONS                        *****/
     69   /*****                                                               *****/
     70   /*************************************************************************/
     71   /*************************************************************************/
     72 
     73   static void
     74   gxv_bsln_LookupValue_validate( FT_UShort            glyph,
     75                                  GXV_LookupValueCPtr  value_p,
     76                                  GXV_Validator        gxvalid )
     77   {
     78     FT_UShort     v = value_p->u;
     79     FT_UShort*    ctlPoints;
     80 
     81     FT_UNUSED( glyph );
     82 
     83 
     84     GXV_NAME_ENTER( "lookup value" );
     85 
     86     if ( v >= GXV_BSLN_VALUE_COUNT )
     87       FT_INVALID_DATA;
     88 
     89     ctlPoints = (FT_UShort*)GXV_BSLN_DATA( ctlPoints_p );
     90     if ( ctlPoints && ctlPoints[v] == GXV_BSLN_VALUE_EMPTY )
     91       FT_INVALID_DATA;
     92 
     93     GXV_EXIT;
     94   }
     95 
     96 
     97   /*
     98     +===============+ --------+
     99     | lookup header |         |
    100     +===============+         |
    101     | BinSrchHeader |         |
    102     +===============+         |
    103     | lastGlyph[0]  |         |
    104     +---------------+         |
    105     | firstGlyph[0] |         |    head of lookup table
    106     +---------------+         |             +
    107     | offset[0]     |    ->   |          offset            [byte]
    108     +===============+         |             +
    109     | lastGlyph[1]  |         | (glyphID - firstGlyph) * 2 [byte]
    110     +---------------+         |
    111     | firstGlyph[1] |         |
    112     +---------------+         |
    113     | offset[1]     |         |
    114     +===============+         |
    115                               |
    116     ...                       |
    117                               |
    118     16bit value array         |
    119     +===============+         |
    120     |     value     | <-------+
    121     ...
    122   */
    123 
    124   static GXV_LookupValueDesc
    125   gxv_bsln_LookupFmt4_transit( FT_UShort            relative_gindex,
    126                                GXV_LookupValueCPtr  base_value_p,
    127                                FT_Bytes             lookuptbl_limit,
    128                                GXV_Validator        gxvalid )
    129   {
    130     FT_Bytes             p;
    131     FT_Bytes             limit;
    132     FT_UShort            offset;
    133     GXV_LookupValueDesc  value;
    134 
    135     /* XXX: check range ? */
    136     offset = (FT_UShort)( base_value_p->u +
    137                           ( relative_gindex * sizeof ( FT_UShort ) ) );
    138 
    139     p     = gxvalid->lookuptbl_head + offset;
    140     limit = lookuptbl_limit;
    141     GXV_LIMIT_CHECK( 2 );
    142 
    143     value.u = FT_NEXT_USHORT( p );
    144 
    145     return value;
    146   }
    147 
    148 
    149   static void
    150   gxv_bsln_parts_fmt0_validate( FT_Bytes       tables,
    151                                 FT_Bytes       limit,
    152                                 GXV_Validator  gxvalid )
    153   {
    154     FT_Bytes  p = tables;
    155 
    156 
    157     GXV_NAME_ENTER( "parts format 0" );
    158 
    159     /* deltas */
    160     GXV_LIMIT_CHECK( 2 * GXV_BSLN_VALUE_COUNT );
    161 
    162     gxvalid->table_data = NULL;      /* No ctlPoints here. */
    163 
    164     GXV_EXIT;
    165   }
    166 
    167 
    168   static void
    169   gxv_bsln_parts_fmt1_validate( FT_Bytes       tables,
    170                                 FT_Bytes       limit,
    171                                 GXV_Validator  gxvalid )
    172   {
    173     FT_Bytes  p = tables;
    174 
    175 
    176     GXV_NAME_ENTER( "parts format 1" );
    177 
    178     /* deltas */
    179     gxv_bsln_parts_fmt0_validate( p, limit, gxvalid );
    180 
    181     /* mappingData */
    182     gxvalid->lookupval_sign   = GXV_LOOKUPVALUE_UNSIGNED;
    183     gxvalid->lookupval_func   = gxv_bsln_LookupValue_validate;
    184     gxvalid->lookupfmt4_trans = gxv_bsln_LookupFmt4_transit;
    185     gxv_LookupTable_validate( p + 2 * GXV_BSLN_VALUE_COUNT,
    186                               limit,
    187                               gxvalid );
    188 
    189     GXV_EXIT;
    190   }
    191 
    192 
    193   static void
    194   gxv_bsln_parts_fmt2_validate( FT_Bytes       tables,
    195                                 FT_Bytes       limit,
    196                                 GXV_Validator  gxvalid )
    197   {
    198     FT_Bytes   p = tables;
    199 
    200     FT_UShort  stdGlyph;
    201     FT_UShort  ctlPoint;
    202     FT_Int     i;
    203 
    204     FT_UShort  defaultBaseline = GXV_BSLN_DATA( defaultBaseline );
    205 
    206 
    207     GXV_NAME_ENTER( "parts format 2" );
    208 
    209     GXV_LIMIT_CHECK( 2 + ( 2 * GXV_BSLN_VALUE_COUNT ) );
    210 
    211     /* stdGlyph */
    212     stdGlyph = FT_NEXT_USHORT( p );
    213     GXV_TRACE(( " (stdGlyph = %u)\n", stdGlyph ));
    214 
    215     gxv_glyphid_validate( stdGlyph, gxvalid );
    216 
    217     /* Record the position of ctlPoints */
    218     GXV_BSLN_DATA( ctlPoints_p ) = p;
    219 
    220     /* ctlPoints */
    221     for ( i = 0; i < GXV_BSLN_VALUE_COUNT; i++ )
    222     {
    223       ctlPoint = FT_NEXT_USHORT( p );
    224       if ( ctlPoint == GXV_BSLN_VALUE_EMPTY )
    225       {
    226         if ( i == defaultBaseline )
    227           FT_INVALID_DATA;
    228       }
    229       else
    230         gxv_ctlPoint_validate( stdGlyph, ctlPoint, gxvalid );
    231     }
    232 
    233     GXV_EXIT;
    234   }
    235 
    236 
    237   static void
    238   gxv_bsln_parts_fmt3_validate( FT_Bytes       tables,
    239                                 FT_Bytes       limit,
    240                                 GXV_Validator  gxvalid)
    241   {
    242     FT_Bytes  p = tables;
    243 
    244 
    245     GXV_NAME_ENTER( "parts format 3" );
    246 
    247     /* stdGlyph + ctlPoints */
    248     gxv_bsln_parts_fmt2_validate( p, limit, gxvalid );
    249 
    250     /* mappingData */
    251     gxvalid->lookupval_sign   = GXV_LOOKUPVALUE_UNSIGNED;
    252     gxvalid->lookupval_func   = gxv_bsln_LookupValue_validate;
    253     gxvalid->lookupfmt4_trans = gxv_bsln_LookupFmt4_transit;
    254     gxv_LookupTable_validate( p + ( 2 + 2 * GXV_BSLN_VALUE_COUNT ),
    255                               limit,
    256                               gxvalid );
    257 
    258     GXV_EXIT;
    259   }
    260 
    261 
    262   /*************************************************************************/
    263   /*************************************************************************/
    264   /*****                                                               *****/
    265   /*****                         bsln TABLE                            *****/
    266   /*****                                                               *****/
    267   /*************************************************************************/
    268   /*************************************************************************/
    269 
    270   FT_LOCAL_DEF( void )
    271   gxv_bsln_validate( FT_Bytes      table,
    272                      FT_Face       face,
    273                      FT_Validator  ftvalid )
    274   {
    275     GXV_ValidatorRec  gxvalidrec;
    276     GXV_Validator     gxvalid = &gxvalidrec;
    277 
    278     GXV_bsln_DataRec  bslnrec;
    279     GXV_bsln_Data     bsln = &bslnrec;
    280 
    281     FT_Bytes  p     = table;
    282     FT_Bytes  limit = 0;
    283 
    284     FT_ULong   version;
    285     FT_UShort  format;
    286     FT_UShort  defaultBaseline;
    287 
    288     GXV_Validate_Func  fmt_funcs_table [] =
    289     {
    290       gxv_bsln_parts_fmt0_validate,
    291       gxv_bsln_parts_fmt1_validate,
    292       gxv_bsln_parts_fmt2_validate,
    293       gxv_bsln_parts_fmt3_validate,
    294     };
    295 
    296 
    297     gxvalid->root       = ftvalid;
    298     gxvalid->table_data = bsln;
    299     gxvalid->face       = face;
    300 
    301     FT_TRACE3(( "validating `bsln' table\n" ));
    302     GXV_INIT;
    303 
    304 
    305     GXV_LIMIT_CHECK( 4 + 2 + 2 );
    306     version         = FT_NEXT_ULONG( p );
    307     format          = FT_NEXT_USHORT( p );
    308     defaultBaseline = FT_NEXT_USHORT( p );
    309 
    310     /* only version 1.0 is defined (1996) */
    311     if ( version != 0x00010000UL )
    312       FT_INVALID_FORMAT;
    313 
    314     /* only format 1, 2, 3 are defined (1996) */
    315     GXV_TRACE(( " (format = %d)\n", format ));
    316     if ( format > 3 )
    317       FT_INVALID_FORMAT;
    318 
    319     if ( defaultBaseline > 31 )
    320       FT_INVALID_FORMAT;
    321 
    322     bsln->defaultBaseline = defaultBaseline;
    323 
    324     fmt_funcs_table[format]( p, limit, gxvalid );
    325 
    326     FT_TRACE4(( "\n" ));
    327   }
    328 
    329 
    330 /* arch-tag: ebe81143-fdaa-4c68-a4d1-b57227daa3bc
    331    (do not change this comment) */
    332 
    333 
    334 /* END */
    335