misc/libfreetype/src/gxvalid/gxvtrak.c
changeset 9431 0f5961910e27
parent 9357 a501f5ec7b34
parent 9429 7a97a554ac80
child 9433 f0a8ac191839
equal deleted inserted replaced
9357:a501f5ec7b34 9431:0f5961910e27
     1 /***************************************************************************/
       
     2 /*                                                                         */
       
     3 /*  gxvtrak.c                                                              */
       
     4 /*                                                                         */
       
     5 /*    TrueTypeGX/AAT trak table validation (body).                         */
       
     6 /*                                                                         */
       
     7 /*  Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */
       
     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 /*                                                                         */
       
    20 /* gxvalid is derived from both gxlayout module and otvalid module.        */
       
    21 /* Development of gxlayout is supported by the Information-technology      */
       
    22 /* Promotion Agency(IPA), Japan.                                           */
       
    23 /*                                                                         */
       
    24 /***************************************************************************/
       
    25 
       
    26 
       
    27 #include "gxvalid.h"
       
    28 #include "gxvcommn.h"
       
    29 
       
    30 
       
    31   /*************************************************************************/
       
    32   /*                                                                       */
       
    33   /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
       
    34   /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
       
    35   /* messages during execution.                                            */
       
    36   /*                                                                       */
       
    37 #undef  FT_COMPONENT
       
    38 #define FT_COMPONENT  trace_gxvtrak
       
    39 
       
    40 
       
    41   /*************************************************************************/
       
    42   /*************************************************************************/
       
    43   /*****                                                               *****/
       
    44   /*****                      Data and Types                           *****/
       
    45   /*****                                                               *****/
       
    46   /*************************************************************************/
       
    47   /*************************************************************************/
       
    48 
       
    49     /*
       
    50      * referred track table format specification:
       
    51      * http://developer.apple.com/fonts/TTRefMan/RM06/Chap6trak.html
       
    52      * last update was 1996.
       
    53      * ----------------------------------------------
       
    54      * [MINIMUM HEADER]: GXV_TRAK_SIZE_MIN
       
    55      * version          (fixed:  32bit) = 0x00010000
       
    56      * format           (uint16: 16bit) = 0 is only defined (1996)
       
    57      * horizOffset      (uint16: 16bit)
       
    58      * vertOffset       (uint16: 16bit)
       
    59      * reserved         (uint16: 16bit) = 0
       
    60      * ----------------------------------------------
       
    61      * [VARIABLE BODY]:
       
    62      * horizData
       
    63      *   header         ( 2 + 2 + 4
       
    64      *   trackTable       + nTracks * ( 4 + 2 + 2 )
       
    65      *   sizeTable        + nSizes * 4 )
       
    66      * ----------------------------------------------
       
    67      * vertData
       
    68      *   header         ( 2 + 2 + 4
       
    69      *   trackTable       + nTracks * ( 4 + 2 + 2 )
       
    70      *   sizeTable        + nSizes * 4 )
       
    71      * ----------------------------------------------
       
    72      */
       
    73   typedef struct  GXV_trak_DataRec_
       
    74   {
       
    75     FT_UShort  trackValueOffset_min;
       
    76     FT_UShort  trackValueOffset_max;
       
    77 
       
    78   } GXV_trak_DataRec, *GXV_trak_Data;
       
    79 
       
    80 
       
    81 #define GXV_TRAK_DATA( FIELD )  GXV_TABLE_DATA( trak, FIELD )
       
    82 
       
    83 
       
    84   /*************************************************************************/
       
    85   /*************************************************************************/
       
    86   /*****                                                               *****/
       
    87   /*****                      UTILITY FUNCTIONS                        *****/
       
    88   /*****                                                               *****/
       
    89   /*************************************************************************/
       
    90   /*************************************************************************/
       
    91 
       
    92   static void
       
    93   gxv_trak_trackTable_validate( FT_Bytes       table,
       
    94                                 FT_Bytes       limit,
       
    95                                 FT_UShort      nTracks,
       
    96                                 GXV_Validator  valid )
       
    97   {
       
    98     FT_Bytes   p = table;
       
    99 
       
   100     FT_Fixed   track;
       
   101     FT_UShort  nameIndex;
       
   102     FT_UShort  offset;
       
   103     FT_UShort  i;
       
   104 
       
   105 
       
   106     GXV_NAME_ENTER( "trackTable" );
       
   107 
       
   108     GXV_TRAK_DATA( trackValueOffset_min ) = 0xFFFFU;
       
   109     GXV_TRAK_DATA( trackValueOffset_max ) = 0x0000;
       
   110 
       
   111     for ( i = 0; i < nTracks; i ++ )
       
   112     {
       
   113       GXV_LIMIT_CHECK( 4 + 2 + 2 );
       
   114       track     = FT_NEXT_LONG( p );
       
   115       nameIndex = FT_NEXT_USHORT( p );
       
   116       offset    = FT_NEXT_USHORT( p );
       
   117 
       
   118       if ( offset < GXV_TRAK_DATA( trackValueOffset_min ) )
       
   119         GXV_TRAK_DATA( trackValueOffset_min ) = offset;
       
   120       if ( offset > GXV_TRAK_DATA( trackValueOffset_max ) )
       
   121         GXV_TRAK_DATA( trackValueOffset_max ) = offset;
       
   122 
       
   123       gxv_sfntName_validate( nameIndex, 256, 32767, valid );
       
   124     }
       
   125 
       
   126     valid->subtable_length = p - table;
       
   127     GXV_EXIT;
       
   128   }
       
   129 
       
   130 
       
   131   static void
       
   132   gxv_trak_trackData_validate( FT_Bytes       table,
       
   133                                FT_Bytes       limit,
       
   134                                GXV_Validator  valid )
       
   135   {
       
   136     FT_Bytes   p = table;
       
   137     FT_UShort  nTracks;
       
   138     FT_UShort  nSizes;
       
   139     FT_ULong   sizeTableOffset;
       
   140 
       
   141     GXV_ODTECT( 4, odtect );
       
   142 
       
   143 
       
   144     GXV_ODTECT_INIT( odtect );
       
   145     GXV_NAME_ENTER( "trackData" );
       
   146 
       
   147     /* read the header of trackData */
       
   148     GXV_LIMIT_CHECK( 2 + 2 + 4 );
       
   149     nTracks         = FT_NEXT_USHORT( p );
       
   150     nSizes          = FT_NEXT_USHORT( p );
       
   151     sizeTableOffset = FT_NEXT_ULONG( p );
       
   152 
       
   153     gxv_odtect_add_range( table, p - table, "trackData header", odtect );
       
   154 
       
   155     /* validate trackTable */
       
   156     gxv_trak_trackTable_validate( p, limit, nTracks, valid );
       
   157     gxv_odtect_add_range( p, valid->subtable_length,
       
   158                           "trackTable", odtect );
       
   159 
       
   160     /* sizeTable is array of FT_Fixed, don't check contents */
       
   161     p = valid->root->base + sizeTableOffset;
       
   162     GXV_LIMIT_CHECK( nSizes * 4 );
       
   163     gxv_odtect_add_range( p, nSizes * 4, "sizeTable", odtect );
       
   164 
       
   165     /* validate trackValueOffet */
       
   166     p = valid->root->base + GXV_TRAK_DATA( trackValueOffset_min );
       
   167     if ( limit - p < nTracks * nSizes * 2 )
       
   168       GXV_TRACE(( "too short trackValue array\n" ));
       
   169 
       
   170     p = valid->root->base + GXV_TRAK_DATA( trackValueOffset_max );
       
   171     GXV_LIMIT_CHECK( nSizes * 2 );
       
   172 
       
   173     gxv_odtect_add_range( valid->root->base
       
   174                             + GXV_TRAK_DATA( trackValueOffset_min ),
       
   175                           GXV_TRAK_DATA( trackValueOffset_max )
       
   176                             - GXV_TRAK_DATA( trackValueOffset_min )
       
   177                             + nSizes * 2,
       
   178                           "trackValue array", odtect );
       
   179 
       
   180     gxv_odtect_validate( odtect, valid );
       
   181 
       
   182     GXV_EXIT;
       
   183   }
       
   184 
       
   185 
       
   186   /*************************************************************************/
       
   187   /*************************************************************************/
       
   188   /*****                                                               *****/
       
   189   /*****                          trak TABLE                           *****/
       
   190   /*****                                                               *****/
       
   191   /*************************************************************************/
       
   192   /*************************************************************************/
       
   193 
       
   194   FT_LOCAL_DEF( void )
       
   195   gxv_trak_validate( FT_Bytes      table,
       
   196                      FT_Face       face,
       
   197                      FT_Validator  ftvalid )
       
   198   {
       
   199     FT_Bytes          p = table;
       
   200     FT_Bytes          limit = 0;
       
   201     FT_Offset         table_size;
       
   202 
       
   203     GXV_ValidatorRec  validrec;
       
   204     GXV_Validator     valid = &validrec;
       
   205     GXV_trak_DataRec  trakrec;
       
   206     GXV_trak_Data     trak = &trakrec;
       
   207 
       
   208     FT_ULong   version;
       
   209     FT_UShort  format;
       
   210     FT_UShort  horizOffset;
       
   211     FT_UShort  vertOffset;
       
   212     FT_UShort  reserved;
       
   213 
       
   214 
       
   215     GXV_ODTECT( 3, odtect );
       
   216 
       
   217     GXV_ODTECT_INIT( odtect );
       
   218     valid->root       = ftvalid;
       
   219     valid->table_data = trak;
       
   220     valid->face       = face;
       
   221 
       
   222     limit      = valid->root->limit;
       
   223     table_size = limit - table;
       
   224 
       
   225     FT_TRACE3(( "validating `trak' table\n" ));
       
   226     GXV_INIT;
       
   227 
       
   228     GXV_LIMIT_CHECK( 4 + 2 + 2 + 2 + 2 );
       
   229     version     = FT_NEXT_ULONG( p );
       
   230     format      = FT_NEXT_USHORT( p );
       
   231     horizOffset = FT_NEXT_USHORT( p );
       
   232     vertOffset  = FT_NEXT_USHORT( p );
       
   233     reserved    = FT_NEXT_USHORT( p );
       
   234 
       
   235     GXV_TRACE(( " (version = 0x%08x)\n", version ));
       
   236     GXV_TRACE(( " (format = 0x%04x)\n", format ));
       
   237     GXV_TRACE(( " (horizOffset = 0x%04x)\n", horizOffset ));
       
   238     GXV_TRACE(( " (vertOffset = 0x%04x)\n", vertOffset ));
       
   239     GXV_TRACE(( " (reserved = 0x%04x)\n", reserved ));
       
   240 
       
   241     /* Version 1.0 (always:1996) */
       
   242     if ( version != 0x00010000UL )
       
   243       FT_INVALID_FORMAT;
       
   244 
       
   245     /* format 0 (always:1996) */
       
   246     if ( format != 0x0000 )
       
   247       FT_INVALID_FORMAT;
       
   248 
       
   249     GXV_32BIT_ALIGNMENT_VALIDATE( horizOffset );
       
   250     GXV_32BIT_ALIGNMENT_VALIDATE( vertOffset );
       
   251 
       
   252     /* Reserved Fixed Value (always) */
       
   253     if ( reserved != 0x0000 )
       
   254       FT_INVALID_DATA;
       
   255 
       
   256     /* validate trackData */
       
   257     if ( 0 < horizOffset )
       
   258     {
       
   259       gxv_trak_trackData_validate( table + horizOffset, limit, valid );
       
   260       gxv_odtect_add_range( table + horizOffset, valid->subtable_length,
       
   261                             "horizJustData", odtect );
       
   262     }
       
   263 
       
   264     if ( 0 < vertOffset )
       
   265     {
       
   266       gxv_trak_trackData_validate( table + vertOffset, limit, valid );
       
   267       gxv_odtect_add_range( table + vertOffset, valid->subtable_length,
       
   268                             "vertJustData", odtect );
       
   269     }
       
   270 
       
   271     gxv_odtect_validate( odtect, valid );
       
   272 
       
   273     FT_TRACE4(( "\n" ));
       
   274   }
       
   275 
       
   276 
       
   277 /* END */