source: trunk/poppler/freetype2/src/gxvalid/gxvfeat.c @ 251

Last change on this file since 251 was 251, checked in by Eugene Romanenko, 13 years ago

PDF plugin: freetype library updated to version 2.3.5

File size: 11.4 KB
Line 
1/***************************************************************************/
2/*                                                                         */
3/*  gxvfeat.c                                                              */
4/*                                                                         */
5/*    TrueTypeGX/AAT feat table validation (body).                         */
6/*                                                                         */
7/*  Copyright 2004, 2005, 2008 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#include "gxvfeat.h"
31
32
33  /*************************************************************************/
34  /*                                                                       */
35  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
36  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
37  /* messages during execution.                                            */
38  /*                                                                       */
39#undef  FT_COMPONENT
40#define FT_COMPONENT  trace_gxvfeat
41
42
43  /*************************************************************************/
44  /*************************************************************************/
45  /*****                                                               *****/
46  /*****                      Data and Types                           *****/
47  /*****                                                               *****/
48  /*************************************************************************/
49  /*************************************************************************/
50
51  typedef struct  GXV_feat_DataRec_
52  {
53    FT_UInt    reserved_size;
54    FT_UShort  feature;
55    FT_UShort  setting;
56
57  } GXV_feat_DataRec, *GXV_feat_Data;
58
59
60#define GXV_FEAT_DATA( field )  GXV_TABLE_DATA( feat, field )
61
62
63  typedef enum  GXV_FeatureFlagsMask_
64  {
65    GXV_FEAT_MASK_EXCLUSIVE_SETTINGS = 0x8000U,
66    GXV_FEAT_MASK_DYNAMIC_DEFAULT    = 0x4000,
67    GXV_FEAT_MASK_UNUSED             = 0x3F00,
68    GXV_FEAT_MASK_DEFAULT_SETTING    = 0x00FF
69
70  } GXV_FeatureFlagsMask;
71
72
73  /*************************************************************************/
74  /*************************************************************************/
75  /*****                                                               *****/
76  /*****                      UTILITY FUNCTIONS                        *****/
77  /*****                                                               *****/
78  /*************************************************************************/
79  /*************************************************************************/
80
81  static void
82  gxv_feat_registry_validate( FT_UShort      feature,
83                              FT_UShort      nSettings,
84                              FT_Bool        exclusive,
85                              GXV_Validator  valid )
86  {
87    GXV_NAME_ENTER( "feature in registry" );
88
89    GXV_TRACE(( " (feature = %u)\n", feature ));
90
91    if ( feature >= gxv_feat_registry_length )
92    {
93      GXV_TRACE(( "feature number %d is out of range %d\n",
94                  feature, gxv_feat_registry_length ));
95      if ( valid->root->level == FT_VALIDATE_PARANOID )
96        FT_INVALID_DATA;
97      goto Exit;
98    }
99
100    if ( gxv_feat_registry[feature].existence == 0 )
101    {
102      GXV_TRACE(( "feature number %d is in defined range but doesn't exist\n",
103                  feature ));
104      if ( valid->root->level == FT_VALIDATE_PARANOID )
105        FT_INVALID_DATA;
106      goto Exit;
107    }
108
109    if ( gxv_feat_registry[feature].apple_reserved )
110    {
111      /* Don't use here. Apple is reserved. */
112      GXV_TRACE(( "feature number %d is reserved by Apple\n", feature ));
113      if ( valid->root->level >= FT_VALIDATE_TIGHT )
114        FT_INVALID_DATA;
115    }
116
117    if ( nSettings != gxv_feat_registry[feature].nSettings )
118    {
119      GXV_TRACE(( "feature %d: nSettings %d != defined nSettings %d\n",
120                  feature, nSettings,
121                  gxv_feat_registry[feature].nSettings ));
122      if ( valid->root->level >= FT_VALIDATE_TIGHT )
123        FT_INVALID_DATA;
124    }
125
126    if ( exclusive != gxv_feat_registry[feature].exclusive )
127    {
128      GXV_TRACE(( "exclusive flag %d differs from predefined value\n",
129                  exclusive ));
130      if ( valid->root->level >= FT_VALIDATE_TIGHT )
131        FT_INVALID_DATA;
132    }
133
134  Exit:
135    GXV_EXIT;
136  }
137
138
139  static void
140  gxv_feat_name_index_validate( FT_Bytes       table,
141                                FT_Bytes       limit,
142                                GXV_Validator  valid )
143  {
144    FT_Bytes  p = table;
145
146    FT_Short  nameIndex;
147
148
149    GXV_NAME_ENTER( "nameIndex" );
150
151    GXV_LIMIT_CHECK( 2 );
152    nameIndex = FT_NEXT_SHORT ( p );
153    GXV_TRACE(( " (nameIndex = %d)\n", nameIndex ));
154
155    gxv_sfntName_validate( (FT_UShort)nameIndex,
156                           255,
157                           32768U,
158                           valid );
159
160    GXV_EXIT;
161  }
162
163
164  static void
165  gxv_feat_setting_validate( FT_Bytes       table,
166                             FT_Bytes       limit,
167                             FT_Bool        exclusive,
168                             GXV_Validator  valid )
169  {
170    FT_Bytes   p = table;
171    FT_UShort  setting;
172
173
174    GXV_NAME_ENTER( "setting" );
175
176    GXV_LIMIT_CHECK( 2 );
177
178    setting = FT_NEXT_USHORT( p );
179
180    /* If we have exclusive setting, the setting should be odd. */
181    if ( exclusive && ( setting % 2 ) == 0 )
182      FT_INVALID_DATA;
183
184    gxv_feat_name_index_validate( p, limit, valid );
185
186    GXV_FEAT_DATA( setting ) = setting;
187
188    GXV_EXIT;
189  }
190
191
192  static void
193  gxv_feat_name_validate( FT_Bytes       table,
194                          FT_Bytes       limit,
195                          GXV_Validator  valid )
196  {
197    FT_Bytes   p             = table;
198    FT_UInt    reserved_size = GXV_FEAT_DATA( reserved_size );
199
200    FT_UShort  feature;
201    FT_UShort  nSettings;
202    FT_UInt    settingTable;
203    FT_UShort  featureFlags;
204
205    FT_Bool    exclusive;
206    FT_Int     last_setting;
207    FT_UInt    i;
208
209
210    GXV_NAME_ENTER( "name" );
211
212    /* feature + nSettings + settingTable + featureFlags */
213    GXV_LIMIT_CHECK( 2 + 2 + 4 + 2 );
214
215    feature = FT_NEXT_USHORT( p );
216    GXV_FEAT_DATA( feature ) = feature;
217
218    nSettings    = FT_NEXT_USHORT( p );
219    settingTable = FT_NEXT_ULONG ( p );
220    featureFlags = FT_NEXT_USHORT( p );
221
222    if ( settingTable < reserved_size )
223      FT_INVALID_OFFSET;
224
225    if ( valid->root->level == FT_VALIDATE_PARANOID   &&
226         ( featureFlags & GXV_FEAT_MASK_UNUSED ) == 0 )
227      FT_INVALID_DATA;
228
229    exclusive = FT_BOOL( featureFlags & GXV_FEAT_MASK_EXCLUSIVE_SETTINGS );
230    if ( exclusive )
231    {
232      FT_Byte  dynamic_default;
233
234
235      if ( featureFlags & GXV_FEAT_MASK_DYNAMIC_DEFAULT )
236        dynamic_default = (FT_Byte)( featureFlags &
237                                     GXV_FEAT_MASK_DEFAULT_SETTING );
238      else
239        dynamic_default = 0;
240
241      /* If exclusive, check whether default setting is in the range. */
242      if ( !( dynamic_default < nSettings ) )
243        FT_INVALID_FORMAT;
244    }
245
246    gxv_feat_registry_validate( feature, nSettings, exclusive, valid );
247
248    gxv_feat_name_index_validate( p, limit, valid );
249
250    p = valid->root->base + settingTable;
251    for ( last_setting = -1, i = 0; i < nSettings; i++ )
252    {
253      gxv_feat_setting_validate( p, limit, exclusive, valid );
254
255      if ( valid->root->level == FT_VALIDATE_PARANOID       &&
256           (FT_Int)GXV_FEAT_DATA( setting ) <= last_setting )
257        FT_INVALID_FORMAT;
258
259      last_setting = (FT_Int)GXV_FEAT_DATA( setting );
260      /* setting + nameIndex */
261      p += ( 2 + 2 );
262    }
263
264    GXV_EXIT;
265  }
266
267
268  /*************************************************************************/
269  /*************************************************************************/
270  /*****                                                               *****/
271  /*****                         feat TABLE                            *****/
272  /*****                                                               *****/
273  /*************************************************************************/
274  /*************************************************************************/
275
276  FT_LOCAL_DEF( void )
277  gxv_feat_validate( FT_Bytes      table,
278                     FT_Face       face,
279                     FT_Validator  ftvalid )
280  {
281    GXV_ValidatorRec  validrec;
282    GXV_Validator     valid = &validrec;
283
284    GXV_feat_DataRec  featrec;
285    GXV_feat_Data     feat = &featrec;
286
287    FT_Bytes          p     = table;
288    FT_Bytes          limit = 0;
289
290    FT_UInt           featureNameCount;
291
292    FT_UInt           i;
293    FT_Int            last_feature;
294
295
296    valid->root       = ftvalid;
297    valid->table_data = feat;
298    valid->face       = face;
299
300    FT_TRACE3(( "validating `feat' table\n" ));
301    GXV_INIT;
302
303    feat->reserved_size = 0;
304
305    /* version + featureNameCount + none_0 + none_1  */
306    GXV_LIMIT_CHECK( 4 + 2 + 2 + 4 );
307    feat->reserved_size += 4 + 2 + 2 + 4;
308
309    if ( FT_NEXT_ULONG( p ) != 0x00010000UL ) /* Version */
310      FT_INVALID_FORMAT;
311
312    featureNameCount = FT_NEXT_USHORT( p );
313    GXV_TRACE(( " (featureNameCount = %d)\n", featureNameCount ));
314
315    if ( valid->root->level != FT_VALIDATE_PARANOID )
316      p += 6;                   /* skip (none) and (none) */
317    else
318    {
319      if ( FT_NEXT_USHORT( p ) != 0 )
320        FT_INVALID_DATA;
321
322      if ( FT_NEXT_ULONG( p )  != 0 )
323        FT_INVALID_DATA;
324    }
325
326    feat->reserved_size += featureNameCount * ( 2 + 2 + 4 + 2 + 2 );
327
328    for ( last_feature = -1, i = 0; i < featureNameCount; i++ )
329    {
330      gxv_feat_name_validate( p, limit, valid );
331
332      if ( valid->root->level == FT_VALIDATE_PARANOID       &&
333           (FT_Int)GXV_FEAT_DATA( feature ) <= last_feature )
334        FT_INVALID_FORMAT;
335
336      last_feature = GXV_FEAT_DATA( feature );
337      p += 2 + 2 + 4 + 2 + 2;
338    }
339
340    FT_TRACE4(( "\n" ));
341  }
342
343
344/* END */
Note: See TracBrowser for help on using the repository browser.