PageRenderTime 40ms CodeModel.GetById 13ms app.highlight 23ms RepoModel.GetById 1ms app.codeStats 0ms

/modules/freetype2/src/gxvalid/gxvjust.c

http://github.com/zpao/v8monkey
C | 630 lines | 415 code | 157 blank | 58 comment | 36 complexity | 986d0ed33f31ba9accd598191122bfa9 MD5 | raw file
  1/***************************************************************************/
  2/*                                                                         */
  3/*  gxvjust.c                                                              */
  4/*                                                                         */
  5/*    TrueTypeGX/AAT just table validation (body).                         */
  6/*                                                                         */
  7/*  Copyright 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#include FT_SFNT_NAMES_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_gxvjust
 41
 42  /*
 43   * referred `just' table format specification:
 44   * http://developer.apple.com/fonts/TTRefMan/RM06/Chap6just.html
 45   * last updated 2000.
 46   * ----------------------------------------------
 47   * [JUST HEADER]: GXV_JUST_HEADER_SIZE
 48   * version     (fixed:  32bit) = 0x00010000
 49   * format      (uint16: 16bit) = 0 is only defined (2000)
 50   * horizOffset (uint16: 16bit)
 51   * vertOffset  (uint16: 16bit)
 52   * ----------------------------------------------
 53   */
 54
 55  typedef struct  GXV_just_DataRec_
 56  {
 57    FT_UShort  wdc_offset_max;
 58    FT_UShort  wdc_offset_min;
 59    FT_UShort  pc_offset_max;
 60    FT_UShort  pc_offset_min;
 61
 62  } GXV_just_DataRec, *GXV_just_Data;
 63
 64
 65#define  GXV_JUST_DATA( a )  GXV_TABLE_DATA( just, a )
 66
 67
 68  static void
 69  gxv_just_wdp_entry_validate( FT_Bytes       table,
 70                               FT_Bytes       limit,
 71                               GXV_Validator  valid )
 72  {
 73    FT_Bytes   p = table;
 74    FT_ULong   justClass;
 75    FT_Fixed   beforeGrowLimit;
 76    FT_Fixed   beforeShrinkGrowLimit;
 77    FT_Fixed   afterGrowLimit;
 78    FT_Fixed   afterShrinkGrowLimit;
 79    FT_UShort  growFlags;
 80    FT_UShort  shrinkFlags;
 81
 82
 83    GXV_LIMIT_CHECK( 4 + 4 + 4 + 4 + 4 + 2 + 2 );
 84    justClass             = FT_NEXT_ULONG( p );
 85    beforeGrowLimit       = FT_NEXT_ULONG( p );
 86    beforeShrinkGrowLimit = FT_NEXT_ULONG( p );
 87    afterGrowLimit        = FT_NEXT_ULONG( p );
 88    afterShrinkGrowLimit  = FT_NEXT_ULONG( p );
 89    growFlags             = FT_NEXT_USHORT( p );
 90    shrinkFlags           = FT_NEXT_USHORT( p );
 91
 92    /* TODO: decode flags for human readability */
 93
 94    valid->subtable_length = p - table;
 95  }
 96
 97
 98  static void
 99  gxv_just_wdc_entry_validate( FT_Bytes       table,
100                               FT_Bytes       limit,
101                               GXV_Validator  valid )
102  {
103    FT_Bytes  p = table;
104    FT_ULong  count, i;
105
106
107    GXV_LIMIT_CHECK( 4 );
108    count = FT_NEXT_ULONG( p );
109    for ( i = 0; i < count; i++ )
110    {
111      GXV_TRACE(( "validating wdc pair %d/%d\n", i + 1, count ));
112      gxv_just_wdp_entry_validate( p, limit, valid );
113      p += valid->subtable_length;
114    }
115
116    valid->subtable_length = p - table;
117  }
118
119
120  static void
121  gxv_just_widthDeltaClusters_validate( FT_Bytes       table,
122                                        FT_Bytes       limit,
123                                        GXV_Validator  valid )
124  {
125    FT_Bytes  p         = table ;
126    FT_Bytes  wdc_end   = table + GXV_JUST_DATA( wdc_offset_max );
127    FT_UInt   i;
128
129
130    GXV_NAME_ENTER( "just justDeltaClusters" );
131
132    if ( limit <= wdc_end )
133      FT_INVALID_OFFSET;
134
135    for ( i = 0; p <= wdc_end; i++ )
136    {
137      gxv_just_wdc_entry_validate( p, limit, valid );
138      p += valid->subtable_length;
139    }
140
141    valid->subtable_length = p - table;
142
143    GXV_EXIT;
144  }
145
146
147  static void
148  gxv_just_actSubrecord_type0_validate( FT_Bytes       table,
149                                        FT_Bytes       limit,
150                                        GXV_Validator  valid )
151  {
152    FT_Bytes   p = table;
153
154    FT_Fixed   lowerLimit;
155    FT_Fixed   upperLimit;
156
157    FT_UShort  order;
158    FT_UShort  decomposedCount;
159
160    FT_UInt    i;
161
162
163    GXV_LIMIT_CHECK( 4 + 4 + 2 + 2 );
164    lowerLimit      = FT_NEXT_ULONG( p );
165    upperLimit      = FT_NEXT_ULONG( p );
166    order           = FT_NEXT_USHORT( p );
167    decomposedCount = FT_NEXT_USHORT( p );
168
169    for ( i = 0; i < decomposedCount; i++ )
170    {
171      FT_UShort glyphs;
172
173
174      GXV_LIMIT_CHECK( 2 );
175      glyphs = FT_NEXT_USHORT( p );
176    }
177
178    valid->subtable_length = p - table;
179  }
180
181
182  static void
183  gxv_just_actSubrecord_type1_validate( FT_Bytes       table,
184                                        FT_Bytes       limit,
185                                        GXV_Validator  valid )
186  {
187    FT_Bytes   p = table;
188    FT_UShort  addGlyph;
189
190
191    GXV_LIMIT_CHECK( 2 );
192    addGlyph = FT_NEXT_USHORT( p );
193
194    valid->subtable_length = p - table;
195  }
196
197
198  static void
199  gxv_just_actSubrecord_type2_validate( FT_Bytes       table,
200                                        FT_Bytes       limit,
201                                        GXV_Validator  valid )
202  {
203    FT_Bytes   p = table;
204    FT_Fixed   substThreshhold; /* Apple misspelled "Threshhold" */
205    FT_UShort  addGlyph;
206    FT_UShort  substGlyph;
207
208
209    GXV_LIMIT_CHECK( 4 + 2 + 2 );
210    substThreshhold = FT_NEXT_ULONG( p );
211    addGlyph        = FT_NEXT_USHORT( p );
212    substGlyph      = FT_NEXT_USHORT( p );
213
214    valid->subtable_length = p - table;
215  }
216
217
218  static void
219  gxv_just_actSubrecord_type4_validate( FT_Bytes       table,
220                                        FT_Bytes       limit,
221                                        GXV_Validator  valid )
222  {
223    FT_Bytes  p = table;
224    FT_ULong  variantsAxis;
225    FT_Fixed  minimumLimit;
226    FT_Fixed  noStretchValue;
227    FT_Fixed  maximumLimit;
228
229
230    GXV_LIMIT_CHECK( 4 + 4 + 4 + 4 );
231    variantsAxis   = FT_NEXT_ULONG( p );
232    minimumLimit   = FT_NEXT_ULONG( p );
233    noStretchValue = FT_NEXT_ULONG( p );
234    maximumLimit   = FT_NEXT_ULONG( p );
235
236    valid->subtable_length = p - table;
237  }
238
239
240  static void
241  gxv_just_actSubrecord_type5_validate( FT_Bytes       table,
242                                        FT_Bytes       limit,
243                                        GXV_Validator  valid )
244  {
245    FT_Bytes   p = table;
246    FT_UShort  flags;
247    FT_UShort  glyph;
248
249
250    GXV_LIMIT_CHECK( 2 + 2 );
251    flags = FT_NEXT_USHORT( p );
252    glyph = FT_NEXT_USHORT( p );
253
254    valid->subtable_length = p - table;
255  }
256
257
258  /* parse single actSubrecord */
259  static void
260  gxv_just_actSubrecord_validate( FT_Bytes       table,
261                                  FT_Bytes       limit,
262                                  GXV_Validator  valid )
263  {
264    FT_Bytes   p = table;
265    FT_UShort  actionClass;
266    FT_UShort  actionType;
267    FT_ULong   actionLength;
268
269
270    GXV_NAME_ENTER( "just actSubrecord" );
271
272    GXV_LIMIT_CHECK( 2 + 2 + 4 );
273    actionClass  = FT_NEXT_USHORT( p );
274    actionType   = FT_NEXT_USHORT( p );
275    actionLength = FT_NEXT_ULONG( p );
276
277    if ( actionType == 0 )
278      gxv_just_actSubrecord_type0_validate( p, limit, valid );
279    else if ( actionType == 1 )
280      gxv_just_actSubrecord_type1_validate( p, limit, valid );
281    else if ( actionType == 2 )
282      gxv_just_actSubrecord_type2_validate( p, limit, valid );
283    else if ( actionType == 3 )
284      ;                         /* Stretch glyph action: no actionData */
285    else if ( actionType == 4 )
286      gxv_just_actSubrecord_type4_validate( p, limit, valid );
287    else if ( actionType == 5 )
288      gxv_just_actSubrecord_type5_validate( p, limit, valid );
289    else
290      FT_INVALID_DATA;
291
292    valid->subtable_length = actionLength;
293
294    GXV_EXIT;
295  }
296
297
298  static void
299  gxv_just_pcActionRecord_validate( FT_Bytes       table,
300                                    FT_Bytes       limit,
301                                    GXV_Validator  valid )
302  {
303    FT_Bytes  p = table;
304    FT_ULong  actionCount;
305    FT_ULong  i;
306
307
308    GXV_LIMIT_CHECK( 4 );
309    actionCount = FT_NEXT_ULONG( p );
310    GXV_TRACE(( "actionCount = %d\n", actionCount ));
311
312    for ( i = 0; i < actionCount; i++ )
313    {
314      gxv_just_actSubrecord_validate( p, limit, valid );
315      p += valid->subtable_length;
316    }
317
318    valid->subtable_length = p - table;
319
320    GXV_EXIT;
321  }
322
323
324  static void
325  gxv_just_pcTable_LookupValue_entry_validate( FT_UShort            glyph,
326                                               GXV_LookupValueCPtr  value_p,
327                                               GXV_Validator        valid )
328  {
329    FT_UNUSED( glyph );
330
331    if ( value_p->u > GXV_JUST_DATA( pc_offset_max ) )
332      GXV_JUST_DATA( pc_offset_max ) = value_p->u;
333    if ( value_p->u < GXV_JUST_DATA( pc_offset_max ) )
334      GXV_JUST_DATA( pc_offset_min ) = value_p->u;
335  }
336
337
338  static void
339  gxv_just_pcLookupTable_validate( FT_Bytes       table,
340                                   FT_Bytes       limit,
341                                   GXV_Validator  valid )
342  {
343    FT_Bytes p = table;
344
345
346    GXV_NAME_ENTER( "just pcLookupTable" );
347    GXV_JUST_DATA( pc_offset_max ) = 0x0000;
348    GXV_JUST_DATA( pc_offset_min ) = 0xFFFFU;
349
350    valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED;
351    valid->lookupval_func = gxv_just_pcTable_LookupValue_entry_validate;
352
353    gxv_LookupTable_validate( p, limit, valid );
354
355    /* subtable_length is set by gxv_LookupTable_validate() */
356
357    GXV_EXIT;
358  }
359
360
361  static void
362  gxv_just_postcompTable_validate( FT_Bytes       table,
363                                   FT_Bytes       limit,
364                                   GXV_Validator  valid )
365  {
366    FT_Bytes  p = table;
367
368
369    GXV_NAME_ENTER( "just postcompTable" );
370
371    gxv_just_pcLookupTable_validate( p, limit, valid );
372    p += valid->subtable_length;
373
374    gxv_just_pcActionRecord_validate( p, limit, valid );
375    p += valid->subtable_length;
376
377    valid->subtable_length = p - table;
378
379    GXV_EXIT;
380  }
381
382
383  static void
384  gxv_just_classTable_entry_validate(
385    FT_Byte                         state,
386    FT_UShort                       flags,
387    GXV_StateTable_GlyphOffsetCPtr  glyphOffset_p,
388    FT_Bytes                        table,
389    FT_Bytes                        limit,
390    GXV_Validator                   valid )
391  {
392    FT_UShort  setMark;
393    FT_UShort  dontAdvance;
394    FT_UShort  markClass;
395    FT_UShort  currentClass;
396
397    FT_UNUSED( state );
398    FT_UNUSED( glyphOffset_p );
399    FT_UNUSED( table );
400    FT_UNUSED( limit );
401    FT_UNUSED( valid );
402
403
404    setMark      = (FT_UShort)( ( flags >> 15 ) & 1    );
405    dontAdvance  = (FT_UShort)( ( flags >> 14 ) & 1    );
406    markClass    = (FT_UShort)( ( flags >> 7  ) & 0x7F );
407    currentClass = (FT_UShort)(   flags         & 0x7F );
408
409    /* TODO: validate markClass & currentClass */
410  }
411
412
413  static void
414  gxv_just_justClassTable_validate ( FT_Bytes       table,
415                                     FT_Bytes       limit,
416                                     GXV_Validator  valid )
417  {
418    FT_Bytes   p = table;
419    FT_UShort  length;
420    FT_UShort  coverage;
421    FT_ULong   subFeatureFlags;
422
423
424    GXV_NAME_ENTER( "just justClassTable" );
425
426    GXV_LIMIT_CHECK( 2 + 2 + 4 );
427    length          = FT_NEXT_USHORT( p );
428    coverage        = FT_NEXT_USHORT( p );
429    subFeatureFlags = FT_NEXT_ULONG( p );
430
431    GXV_TRACE(( "  justClassTable: coverage = 0x%04x (%s)",
432                coverage,
433                ( 0x4000 & coverage ) == 0 ? "ascending" : "descending" ));
434
435    valid->statetable.optdata               = NULL;
436    valid->statetable.optdata_load_func     = NULL;
437    valid->statetable.subtable_setup_func   = NULL;
438    valid->statetable.entry_glyphoffset_fmt = GXV_GLYPHOFFSET_NONE;
439    valid->statetable.entry_validate_func   =
440      gxv_just_classTable_entry_validate;
441
442    gxv_StateTable_validate( p, table + length, valid );
443
444    /* subtable_length is set by gxv_LookupTable_validate() */
445
446    GXV_EXIT;
447  }
448
449
450  static void
451  gxv_just_wdcTable_LookupValue_validate( FT_UShort            glyph,
452                                          GXV_LookupValueCPtr  value_p,
453                                          GXV_Validator        valid )
454  {
455    FT_UNUSED( glyph );
456
457    if ( value_p->u > GXV_JUST_DATA( wdc_offset_max ) )
458      GXV_JUST_DATA( wdc_offset_max ) = value_p->u;
459    if ( value_p->u < GXV_JUST_DATA( wdc_offset_min ) )
460      GXV_JUST_DATA( wdc_offset_min ) = value_p->u;
461  }
462
463
464  static void
465  gxv_just_justData_lookuptable_validate( FT_Bytes       table,
466                                          FT_Bytes       limit,
467                                          GXV_Validator  valid )
468  {
469    FT_Bytes  p = table;
470
471
472    GXV_JUST_DATA( wdc_offset_max ) = 0x0000;
473    GXV_JUST_DATA( wdc_offset_min ) = 0xFFFFU;
474
475    valid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED;
476    valid->lookupval_func = gxv_just_wdcTable_LookupValue_validate;
477
478    gxv_LookupTable_validate( p, limit, valid );
479
480    /* subtable_length is set by gxv_LookupTable_validate() */
481
482    GXV_EXIT;
483  }
484
485
486  /*
487   * gxv_just_justData_validate() parses and validates horizData, vertData.
488   */
489  static void
490  gxv_just_justData_validate( FT_Bytes       table,
491                              FT_Bytes       limit,
492                              GXV_Validator  valid )
493  {
494    /*
495     * following 3 offsets are measured from the start of `just'
496     * (which table points to), not justData
497     */
498    FT_UShort  justClassTableOffset;
499    FT_UShort  wdcTableOffset;
500    FT_UShort  pcTableOffset;
501    FT_Bytes   p = table;
502
503    GXV_ODTECT( 4, odtect );
504
505
506    GXV_NAME_ENTER( "just justData" );
507
508    GXV_ODTECT_INIT( odtect );
509    GXV_LIMIT_CHECK( 2 + 2 + 2 );
510    justClassTableOffset = FT_NEXT_USHORT( p );
511    wdcTableOffset       = FT_NEXT_USHORT( p );
512    pcTableOffset        = FT_NEXT_USHORT( p );
513
514    GXV_TRACE(( " (justClassTableOffset = 0x%04x)\n", justClassTableOffset ));
515    GXV_TRACE(( " (wdcTableOffset = 0x%04x)\n", wdcTableOffset ));
516    GXV_TRACE(( " (pcTableOffset = 0x%04x)\n", pcTableOffset ));
517
518    gxv_just_justData_lookuptable_validate( p, limit, valid );
519    gxv_odtect_add_range( p, valid->subtable_length,
520                          "just_LookupTable", odtect );
521
522    if ( wdcTableOffset )
523    {
524      gxv_just_widthDeltaClusters_validate(
525        valid->root->base + wdcTableOffset, limit, valid );
526      gxv_odtect_add_range( valid->root->base + wdcTableOffset,
527                            valid->subtable_length, "just_wdcTable", odtect );
528    }
529
530    if ( pcTableOffset )
531    {
532      gxv_just_postcompTable_validate( valid->root->base + pcTableOffset,
533                                       limit, valid );
534      gxv_odtect_add_range( valid->root->base + pcTableOffset,
535                            valid->subtable_length, "just_pcTable", odtect );
536    }
537
538    if ( justClassTableOffset )
539    {
540      gxv_just_justClassTable_validate(
541        valid->root->base + justClassTableOffset, limit, valid );
542      gxv_odtect_add_range( valid->root->base + justClassTableOffset,
543                            valid->subtable_length, "just_justClassTable",
544                            odtect );
545    }
546
547    gxv_odtect_validate( odtect, valid );
548
549    GXV_EXIT;
550  }
551
552
553  FT_LOCAL_DEF( void )
554  gxv_just_validate( FT_Bytes      table,
555                     FT_Face       face,
556                     FT_Validator  ftvalid )
557  {
558    FT_Bytes           p     = table;
559    FT_Bytes           limit = 0;
560    FT_Offset          table_size;
561
562    GXV_ValidatorRec   validrec;
563    GXV_Validator      valid = &validrec;
564    GXV_just_DataRec   justrec;
565    GXV_just_Data      just = &justrec;
566
567    FT_ULong           version;
568    FT_UShort          format;
569    FT_UShort          horizOffset;
570    FT_UShort          vertOffset;
571
572    GXV_ODTECT( 3, odtect );
573
574
575    GXV_ODTECT_INIT( odtect );
576
577    valid->root       = ftvalid;
578    valid->table_data = just;
579    valid->face       = face;
580
581    FT_TRACE3(( "validating `just' table\n" ));
582    GXV_INIT;
583
584    limit      = valid->root->limit;
585    table_size = limit - table;
586
587    GXV_LIMIT_CHECK( 4 + 2 + 2 + 2 );
588    version     = FT_NEXT_ULONG( p );
589    format      = FT_NEXT_USHORT( p );
590    horizOffset = FT_NEXT_USHORT( p );
591    vertOffset  = FT_NEXT_USHORT( p );
592    gxv_odtect_add_range( table, p - table, "just header", odtect );
593
594
595    /* Version 1.0 (always:2000) */
596    GXV_TRACE(( " (version = 0x%08x)\n", version ));
597    if ( version != 0x00010000UL )
598      FT_INVALID_FORMAT;
599
600    /* format 0 (always:2000) */
601    GXV_TRACE(( " (format = 0x%04x)\n", format ));
602    if ( format != 0x0000 )
603        FT_INVALID_FORMAT;
604
605    GXV_TRACE(( " (horizOffset = %d)\n", horizOffset  ));
606    GXV_TRACE(( " (vertOffset = %d)\n", vertOffset  ));
607
608
609    /* validate justData */
610    if ( 0 < horizOffset )
611    {
612      gxv_just_justData_validate( table + horizOffset, limit, valid );
613      gxv_odtect_add_range( table + horizOffset, valid->subtable_length,
614                            "horizJustData", odtect );
615    }
616
617    if ( 0 < vertOffset )
618    {
619      gxv_just_justData_validate( table + vertOffset, limit, valid );
620      gxv_odtect_add_range( table + vertOffset, valid->subtable_length,
621                            "vertJustData", odtect );
622    }
623
624    gxv_odtect_validate( odtect, valid );
625
626    FT_TRACE4(( "\n" ));
627  }
628
629
630/* END */