PageRenderTime 40ms CodeModel.GetById 17ms app.highlight 19ms RepoModel.GetById 1ms app.codeStats 0ms

/src/freetype/src/gxvalid/gxvmort2.c

https://bitbucket.org/cabalistic/ogredeps/
C | 311 lines | 211 code | 63 blank | 37 comment | 11 complexity | 2e44d40e897a796227c73fe3d984b265 MD5 | raw file
  1/***************************************************************************/
  2/*                                                                         */
  3/*  gxvmort2.c                                                             */
  4/*                                                                         */
  5/*    TrueTypeGX/AAT mort table validation                                 */
  6/*    body for type2 (Ligature Substitution) subtable.                     */
  7/*                                                                         */
  8/*  Copyright 2005 by 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 "gxvmort.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_gxvmort
 39
 40
 41  typedef struct  GXV_mort_subtable_type2_StateOptRec_
 42  {
 43    FT_UShort  ligActionTable;
 44    FT_UShort  componentTable;
 45    FT_UShort  ligatureTable;
 46    FT_UShort  ligActionTable_length;
 47    FT_UShort  componentTable_length;
 48    FT_UShort  ligatureTable_length;
 49
 50  }  GXV_mort_subtable_type2_StateOptRec,
 51    *GXV_mort_subtable_type2_StateOptRecData;
 52
 53#define GXV_MORT_SUBTABLE_TYPE2_HEADER_SIZE \
 54          ( GXV_STATETABLE_HEADER_SIZE + 2 + 2 + 2 )
 55
 56
 57  static void
 58  gxv_mort_subtable_type2_opttable_load( FT_Bytes       table,
 59                                         FT_Bytes       limit,
 60                                         GXV_Validator  valid )
 61  {
 62    FT_Bytes p = table;
 63    GXV_mort_subtable_type2_StateOptRecData  optdata =
 64      (GXV_mort_subtable_type2_StateOptRecData)valid->statetable.optdata;
 65
 66
 67    GXV_LIMIT_CHECK( 2 + 2 + 2 );
 68    optdata->ligActionTable = FT_NEXT_USHORT( p );
 69    optdata->componentTable = FT_NEXT_USHORT( p );
 70    optdata->ligatureTable  = FT_NEXT_USHORT( p );
 71
 72    GXV_TRACE(( "offset to ligActionTable=0x%04x\n",
 73                optdata->ligActionTable ));
 74    GXV_TRACE(( "offset to componentTable=0x%04x\n",
 75                optdata->componentTable ));
 76    GXV_TRACE(( "offset to ligatureTable=0x%04x\n",
 77                optdata->ligatureTable ));
 78  }
 79
 80
 81  static void
 82  gxv_mort_subtable_type2_subtable_setup( FT_UShort      table_size,
 83                                          FT_UShort      classTable,
 84                                          FT_UShort      stateArray,
 85                                          FT_UShort      entryTable,
 86                                          FT_UShort      *classTable_length_p,
 87                                          FT_UShort      *stateArray_length_p,
 88                                          FT_UShort      *entryTable_length_p,
 89                                          GXV_Validator  valid )
 90  {
 91    FT_UShort  o[6];
 92    FT_UShort  *l[6];
 93    FT_UShort  buff[7];
 94
 95    GXV_mort_subtable_type2_StateOptRecData  optdata =
 96      (GXV_mort_subtable_type2_StateOptRecData)valid->statetable.optdata;
 97
 98
 99    GXV_NAME_ENTER( "subtable boundaries setup" );
100
101    o[0] = classTable;
102    o[1] = stateArray;
103    o[2] = entryTable;
104    o[3] = optdata->ligActionTable;
105    o[4] = optdata->componentTable;
106    o[5] = optdata->ligatureTable;
107    l[0] = classTable_length_p;
108    l[1] = stateArray_length_p;
109    l[2] = entryTable_length_p;
110    l[3] = &(optdata->ligActionTable_length);
111    l[4] = &(optdata->componentTable_length);
112    l[5] = &(optdata->ligatureTable_length);
113
114    gxv_set_length_by_ushort_offset( o, l, buff, 6, table_size, valid );
115
116    GXV_TRACE(( "classTable: offset=0x%04x length=0x%04x\n",
117                classTable, *classTable_length_p ));
118    GXV_TRACE(( "stateArray: offset=0x%04x length=0x%04x\n",
119                stateArray, *stateArray_length_p ));
120    GXV_TRACE(( "entryTable: offset=0x%04x length=0x%04x\n",
121                entryTable, *entryTable_length_p ));
122    GXV_TRACE(( "ligActionTable: offset=0x%04x length=0x%04x\n",
123                optdata->ligActionTable,
124                optdata->ligActionTable_length ));
125    GXV_TRACE(( "componentTable: offset=0x%04x length=0x%04x\n",
126                optdata->componentTable,
127                optdata->componentTable_length ));
128    GXV_TRACE(( "ligatureTable:  offset=0x%04x length=0x%04x\n",
129                optdata->ligatureTable,
130                optdata->ligatureTable_length ));
131
132    GXV_EXIT;
133  }
134
135
136  static void
137  gxv_mort_subtable_type2_ligActionOffset_validate(
138    FT_Bytes       table,
139    FT_UShort      ligActionOffset,
140    GXV_Validator  valid )
141  {
142    /* access ligActionTable */
143    GXV_mort_subtable_type2_StateOptRecData  optdata =
144      (GXV_mort_subtable_type2_StateOptRecData)valid->statetable.optdata;
145
146    FT_Bytes lat_base  = table + optdata->ligActionTable;
147    FT_Bytes p         = table + ligActionOffset;
148    FT_Bytes lat_limit = lat_base + optdata->ligActionTable;
149
150
151    GXV_32BIT_ALIGNMENT_VALIDATE( ligActionOffset );
152    if ( p < lat_base )
153    {
154      GXV_TRACE(( "too short offset 0x%04x: p < lat_base (%d byte rewind)\n",
155                  ligActionOffset, lat_base - p ));
156
157      /* FontValidator, ftxvalidator, ftxdumperfuser warn but continue */
158      GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET );
159    }
160    else if ( lat_limit < p )
161    {
162      GXV_TRACE(( "too large offset 0x%04x: lat_limit < p (%d byte overrun)\n",
163                  ligActionOffset, p - lat_limit ));
164
165      /* FontValidator, ftxvalidator, ftxdumperfuser warn but continue */
166      GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET );
167    }
168    else
169    {
170      /* validate entry in ligActionTable */
171      FT_ULong   lig_action;
172#ifdef GXV_LOAD_UNUSED_VARS
173      FT_UShort  last;
174      FT_UShort  store;
175#endif
176      FT_ULong   offset;
177
178
179      lig_action = FT_NEXT_ULONG( p );
180#ifdef GXV_LOAD_UNUSED_VARS
181      last   = (FT_UShort)( ( lig_action >> 31 ) & 1 );
182      store  = (FT_UShort)( ( lig_action >> 30 ) & 1 );
183#endif
184
185      /* Apple spec defines this offset as a word offset */
186      offset = lig_action & 0x3FFFFFFFUL;
187      if ( offset * 2 < optdata->ligatureTable )
188      {
189        GXV_TRACE(( "too short offset 0x%08x:"
190                    " 2 x offset < ligatureTable (%d byte rewind)\n",
191                     offset, optdata->ligatureTable - offset * 2 ));
192
193        GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET );
194      } else if ( offset * 2 >
195                  optdata->ligatureTable + optdata->ligatureTable_length )
196      {
197        GXV_TRACE(( "too long offset 0x%08x:"
198                    " 2 x offset > ligatureTable + ligatureTable_length"
199                    " (%d byte overrun)\n",
200                     offset,
201                     optdata->ligatureTable + optdata->ligatureTable_length
202                     - offset * 2 ));
203
204        GXV_SET_ERR_IF_PARANOID( FT_INVALID_OFFSET );
205      }
206    }
207  }
208
209
210  static void
211  gxv_mort_subtable_type2_entry_validate(
212    FT_Byte                         state,
213    FT_UShort                       flags,
214    GXV_StateTable_GlyphOffsetCPtr  glyphOffset_p,
215    FT_Bytes                        table,
216    FT_Bytes                        limit,
217    GXV_Validator                   valid )
218  {
219#ifdef GXV_LOAD_UNUSED_VARS
220    FT_UShort setComponent;
221    FT_UShort dontAdvance;
222#endif
223    FT_UShort offset;
224
225    FT_UNUSED( state );
226    FT_UNUSED( glyphOffset_p );
227    FT_UNUSED( limit );
228
229
230#ifdef GXV_LOAD_UNUSED_VARS
231    setComponent = (FT_UShort)( ( flags >> 15 ) & 1 );
232    dontAdvance  = (FT_UShort)( ( flags >> 14 ) & 1 );
233#endif
234
235    offset = (FT_UShort)( flags & 0x3FFFU );
236
237    if ( 0 < offset )
238      gxv_mort_subtable_type2_ligActionOffset_validate( table, offset,
239                                                        valid );
240  }
241
242
243  static void
244  gxv_mort_subtable_type2_ligatureTable_validate( FT_Bytes       table,
245                                                  GXV_Validator  valid )
246  {
247    GXV_mort_subtable_type2_StateOptRecData  optdata =
248      (GXV_mort_subtable_type2_StateOptRecData)valid->statetable.optdata;
249
250    FT_Bytes p     = table + optdata->ligatureTable;
251    FT_Bytes limit = table + optdata->ligatureTable
252                           + optdata->ligatureTable_length;
253
254
255    GXV_NAME_ENTER( "mort chain subtable type2 - substitutionTable" );
256    if ( 0 != optdata->ligatureTable )
257    {
258      /* Apple does not give specification of ligatureTable format */
259      while ( p < limit )
260      {
261        FT_UShort  lig_gid;
262
263
264        GXV_LIMIT_CHECK( 2 );
265        lig_gid = FT_NEXT_USHORT( p );
266
267        if ( valid->face->num_glyphs < lig_gid )
268          GXV_SET_ERR_IF_PARANOID( FT_INVALID_GLYPH_ID );
269      }
270    }
271    GXV_EXIT;
272  }
273
274
275  FT_LOCAL_DEF( void )
276  gxv_mort_subtable_type2_validate( FT_Bytes       table,
277                                    FT_Bytes       limit,
278                                    GXV_Validator  valid )
279  {
280    FT_Bytes  p = table;
281
282    GXV_mort_subtable_type2_StateOptRec  lig_rec;
283
284
285    GXV_NAME_ENTER( "mort chain subtable type2 (Ligature Substitution)" );
286
287    GXV_LIMIT_CHECK( GXV_MORT_SUBTABLE_TYPE2_HEADER_SIZE );
288
289    valid->statetable.optdata =
290      &lig_rec;
291    valid->statetable.optdata_load_func =
292      gxv_mort_subtable_type2_opttable_load;
293    valid->statetable.subtable_setup_func =
294      gxv_mort_subtable_type2_subtable_setup;
295    valid->statetable.entry_glyphoffset_fmt =
296      GXV_GLYPHOFFSET_NONE;
297    valid->statetable.entry_validate_func =
298      gxv_mort_subtable_type2_entry_validate;
299
300    gxv_StateTable_validate( p, limit, valid );
301
302    p += valid->subtable_length;
303    gxv_mort_subtable_type2_ligatureTable_validate( table, valid );
304
305    valid->subtable_length = p - table;
306
307    GXV_EXIT;
308  }
309
310
311/* END */