PageRenderTime 24ms CodeModel.GetById 7ms app.highlight 13ms RepoModel.GetById 2ms app.codeStats 0ms

/src/freetype/src/gxvalid/gxvtrak.c

https://bitbucket.org/cabalistic/ogredeps/
C | 286 lines | 143 code | 60 blank | 83 comment | 15 complexity | 2215414ec2e394cee668b20fc638b58a MD5 | raw file
  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, t;
101    FT_UShort  nameIndex;
102    FT_UShort  offset;
103    FT_UShort  i, j;
104
105
106    GXV_NAME_ENTER( "trackTable" );
107
108    GXV_TRAK_DATA( trackValueOffset_min ) = 0xFFFFU;
109    GXV_TRAK_DATA( trackValueOffset_max ) = 0x0000;
110
111    GXV_LIMIT_CHECK( nTracks * ( 4 + 2 + 2 ) );
112
113    for ( i = 0; i < nTracks; i ++ )
114    {
115      p = table + i * ( 4 + 2 + 2 );
116      track     = FT_NEXT_LONG( p );
117      nameIndex = FT_NEXT_USHORT( p );
118      offset    = FT_NEXT_USHORT( p );
119
120      if ( offset < GXV_TRAK_DATA( trackValueOffset_min ) )
121        GXV_TRAK_DATA( trackValueOffset_min ) = offset;
122      if ( offset > GXV_TRAK_DATA( trackValueOffset_max ) )
123        GXV_TRAK_DATA( trackValueOffset_max ) = offset;
124
125      gxv_sfntName_validate( nameIndex, 256, 32767, valid );
126
127      for ( j = i; j < nTracks; j ++ )
128      {
129         p = table + j * ( 4 + 2 + 2 );
130         t = FT_NEXT_LONG( p );
131         if ( t == track )
132           GXV_TRACE(( "duplicated entries found for track value 0x%x\n",
133                        track ));
134      }
135    }
136
137    valid->subtable_length = p - table;
138    GXV_EXIT;
139  }
140
141
142  static void
143  gxv_trak_trackData_validate( FT_Bytes       table,
144                               FT_Bytes       limit,
145                               GXV_Validator  valid )
146  {
147    FT_Bytes   p = table;
148    FT_UShort  nTracks;
149    FT_UShort  nSizes;
150    FT_ULong   sizeTableOffset;
151
152    GXV_ODTECT( 4, odtect );
153
154
155    GXV_ODTECT_INIT( odtect );
156    GXV_NAME_ENTER( "trackData" );
157
158    /* read the header of trackData */
159    GXV_LIMIT_CHECK( 2 + 2 + 4 );
160    nTracks         = FT_NEXT_USHORT( p );
161    nSizes          = FT_NEXT_USHORT( p );
162    sizeTableOffset = FT_NEXT_ULONG( p );
163
164    gxv_odtect_add_range( table, p - table, "trackData header", odtect );
165
166    /* validate trackTable */
167    gxv_trak_trackTable_validate( p, limit, nTracks, valid );
168    gxv_odtect_add_range( p, valid->subtable_length,
169                          "trackTable", odtect );
170
171    /* sizeTable is array of FT_Fixed, don't check contents */
172    p = valid->root->base + sizeTableOffset;
173    GXV_LIMIT_CHECK( nSizes * 4 );
174    gxv_odtect_add_range( p, nSizes * 4, "sizeTable", odtect );
175
176    /* validate trackValueOffet */
177    p = valid->root->base + GXV_TRAK_DATA( trackValueOffset_min );
178    if ( limit - p < nTracks * nSizes * 2 )
179      GXV_TRACE(( "too short trackValue array\n" ));
180
181    p = valid->root->base + GXV_TRAK_DATA( trackValueOffset_max );
182    GXV_LIMIT_CHECK( nSizes * 2 );
183
184    gxv_odtect_add_range( valid->root->base
185                            + GXV_TRAK_DATA( trackValueOffset_min ),
186                          GXV_TRAK_DATA( trackValueOffset_max )
187                            - GXV_TRAK_DATA( trackValueOffset_min )
188                            + nSizes * 2,
189                          "trackValue array", odtect );
190
191    gxv_odtect_validate( odtect, valid );
192
193    GXV_EXIT;
194  }
195
196
197  /*************************************************************************/
198  /*************************************************************************/
199  /*****                                                               *****/
200  /*****                          trak TABLE                           *****/
201  /*****                                                               *****/
202  /*************************************************************************/
203  /*************************************************************************/
204
205  FT_LOCAL_DEF( void )
206  gxv_trak_validate( FT_Bytes      table,
207                     FT_Face       face,
208                     FT_Validator  ftvalid )
209  {
210    FT_Bytes          p = table;
211    FT_Bytes          limit = 0;
212
213    GXV_ValidatorRec  validrec;
214    GXV_Validator     valid = &validrec;
215    GXV_trak_DataRec  trakrec;
216    GXV_trak_Data     trak = &trakrec;
217
218    FT_ULong   version;
219    FT_UShort  format;
220    FT_UShort  horizOffset;
221    FT_UShort  vertOffset;
222    FT_UShort  reserved;
223
224
225    GXV_ODTECT( 3, odtect );
226
227    GXV_ODTECT_INIT( odtect );
228    valid->root       = ftvalid;
229    valid->table_data = trak;
230    valid->face       = face;
231
232    limit      = valid->root->limit;
233
234    FT_TRACE3(( "validating `trak' table\n" ));
235    GXV_INIT;
236
237    GXV_LIMIT_CHECK( 4 + 2 + 2 + 2 + 2 );
238    version     = FT_NEXT_ULONG( p );
239    format      = FT_NEXT_USHORT( p );
240    horizOffset = FT_NEXT_USHORT( p );
241    vertOffset  = FT_NEXT_USHORT( p );
242    reserved    = FT_NEXT_USHORT( p );
243
244    GXV_TRACE(( " (version = 0x%08x)\n", version ));
245    GXV_TRACE(( " (format = 0x%04x)\n", format ));
246    GXV_TRACE(( " (horizOffset = 0x%04x)\n", horizOffset ));
247    GXV_TRACE(( " (vertOffset = 0x%04x)\n", vertOffset ));
248    GXV_TRACE(( " (reserved = 0x%04x)\n", reserved ));
249
250    /* Version 1.0 (always:1996) */
251    if ( version != 0x00010000UL )
252      FT_INVALID_FORMAT;
253
254    /* format 0 (always:1996) */
255    if ( format != 0x0000 )
256      FT_INVALID_FORMAT;
257
258    GXV_32BIT_ALIGNMENT_VALIDATE( horizOffset );
259    GXV_32BIT_ALIGNMENT_VALIDATE( vertOffset );
260
261    /* Reserved Fixed Value (always) */
262    if ( reserved != 0x0000 )
263      FT_INVALID_DATA;
264
265    /* validate trackData */
266    if ( 0 < horizOffset )
267    {
268      gxv_trak_trackData_validate( table + horizOffset, limit, valid );
269      gxv_odtect_add_range( table + horizOffset, valid->subtable_length,
270                            "horizJustData", odtect );
271    }
272
273    if ( 0 < vertOffset )
274    {
275      gxv_trak_trackData_validate( table + vertOffset, limit, valid );
276      gxv_odtect_add_range( table + vertOffset, valid->subtable_length,
277                            "vertJustData", odtect );
278    }
279
280    gxv_odtect_validate( odtect, valid );
281
282    FT_TRACE4(( "\n" ));
283  }
284
285
286/* END */