~ubuntu-branches/ubuntu/vivid/emscripten/vivid

« back to all changes in this revision

Viewing changes to tests/freetype/src/otvalid/otvgsub.c

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-05-02 13:11:51 UTC
  • Revision ID: package-import@ubuntu.com-20130502131151-q8dvteqr1ef2x7xz
Tags: upstream-1.4.1~20130504~adb56cb
ImportĀ upstreamĀ versionĀ 1.4.1~20130504~adb56cb

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************/
 
2
/*                                                                         */
 
3
/*  otvgsub.c                                                              */
 
4
/*                                                                         */
 
5
/*    OpenType GSUB table validation (body).                               */
 
6
/*                                                                         */
 
7
/*  Copyright 2004, 2005, 2007 by                                          */
 
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
#include "otvalid.h"
 
20
#include "otvcommn.h"
 
21
 
 
22
 
 
23
  /*************************************************************************/
 
24
  /*                                                                       */
 
25
  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
 
26
  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
 
27
  /* messages during execution.                                            */
 
28
  /*                                                                       */
 
29
#undef  FT_COMPONENT
 
30
#define FT_COMPONENT  trace_otvgsub
 
31
 
 
32
 
 
33
  /*************************************************************************/
 
34
  /*************************************************************************/
 
35
  /*****                                                               *****/
 
36
  /*****                  GSUB LOOKUP TYPE 1                           *****/
 
37
  /*****                                                               *****/
 
38
  /*************************************************************************/
 
39
  /*************************************************************************/
 
40
 
 
41
  /* uses valid->glyph_count */
 
42
 
 
43
  static void
 
44
  otv_SingleSubst_validate( FT_Bytes       table,
 
45
                            OTV_Validator  valid )
 
46
  {
 
47
    FT_Bytes  p = table;
 
48
    FT_UInt   SubstFormat;
 
49
 
 
50
 
 
51
    OTV_NAME_ENTER( "SingleSubst" );
 
52
 
 
53
    OTV_LIMIT_CHECK( 2 );
 
54
    SubstFormat = FT_NEXT_USHORT( p );
 
55
 
 
56
    OTV_TRACE(( " (format %d)\n", SubstFormat ));
 
57
 
 
58
    switch ( SubstFormat )
 
59
    {
 
60
    case 1:     /* SingleSubstFormat1 */
 
61
      {
 
62
        FT_Bytes  Coverage;
 
63
        FT_Int    DeltaGlyphID;
 
64
        FT_Long   idx;
 
65
 
 
66
 
 
67
        OTV_LIMIT_CHECK( 4 );
 
68
        Coverage     = table + FT_NEXT_USHORT( p );
 
69
        DeltaGlyphID = FT_NEXT_SHORT( p );
 
70
 
 
71
        otv_Coverage_validate( Coverage, valid, -1 );
 
72
 
 
73
        idx = otv_Coverage_get_first( Coverage ) + DeltaGlyphID;
 
74
        if ( idx < 0 )
 
75
          FT_INVALID_DATA;
 
76
 
 
77
        idx = otv_Coverage_get_last( Coverage ) + DeltaGlyphID;
 
78
        if ( (FT_UInt)idx >= valid->glyph_count )
 
79
          FT_INVALID_DATA;
 
80
      }
 
81
      break;
 
82
 
 
83
    case 2:     /* SingleSubstFormat2 */
 
84
      {
 
85
        FT_UInt  Coverage, GlyphCount;
 
86
 
 
87
 
 
88
        OTV_LIMIT_CHECK( 4 );
 
89
        Coverage   = FT_NEXT_USHORT( p );
 
90
        GlyphCount = FT_NEXT_USHORT( p );
 
91
 
 
92
        OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount ));
 
93
 
 
94
        otv_Coverage_validate( table + Coverage, valid, GlyphCount );
 
95
 
 
96
        OTV_LIMIT_CHECK( GlyphCount * 2 );
 
97
 
 
98
        /* Substitute */
 
99
        for ( ; GlyphCount > 0; GlyphCount-- )
 
100
          if ( FT_NEXT_USHORT( p ) >= valid->glyph_count )
 
101
            FT_INVALID_GLYPH_ID;
 
102
      }
 
103
      break;
 
104
 
 
105
    default:
 
106
      FT_INVALID_FORMAT;
 
107
    }
 
108
 
 
109
    OTV_EXIT;
 
110
  }
 
111
 
 
112
 
 
113
  /*************************************************************************/
 
114
  /*************************************************************************/
 
115
  /*****                                                               *****/
 
116
  /*****                  GSUB LOOKUP TYPE 2                           *****/
 
117
  /*****                                                               *****/
 
118
  /*************************************************************************/
 
119
  /*************************************************************************/
 
120
 
 
121
  /* sets valid->extra1 (glyph count) */
 
122
 
 
123
  static void
 
124
  otv_MultipleSubst_validate( FT_Bytes       table,
 
125
                              OTV_Validator  valid )
 
126
  {
 
127
    FT_Bytes  p = table;
 
128
    FT_UInt   SubstFormat;
 
129
 
 
130
 
 
131
    OTV_NAME_ENTER( "MultipleSubst" );
 
132
 
 
133
    OTV_LIMIT_CHECK( 2 );
 
134
    SubstFormat = FT_NEXT_USHORT( p );
 
135
 
 
136
    OTV_TRACE(( " (format %d)\n", SubstFormat ));
 
137
 
 
138
    switch ( SubstFormat )
 
139
    {
 
140
    case 1:
 
141
      valid->extra1 = valid->glyph_count;
 
142
      OTV_NEST2( MultipleSubstFormat1, Sequence );
 
143
      OTV_RUN( table, valid );
 
144
      break;
 
145
 
 
146
    default:
 
147
      FT_INVALID_FORMAT;
 
148
    }
 
149
 
 
150
    OTV_EXIT;
 
151
  }
 
152
 
 
153
 
 
154
  /*************************************************************************/
 
155
  /*************************************************************************/
 
156
  /*****                                                               *****/
 
157
  /*****                    GSUB LOOKUP TYPE 3                         *****/
 
158
  /*****                                                               *****/
 
159
  /*************************************************************************/
 
160
  /*************************************************************************/
 
161
 
 
162
  /* sets valid->extra1 (glyph count) */
 
163
 
 
164
  static void
 
165
  otv_AlternateSubst_validate( FT_Bytes       table,
 
166
                               OTV_Validator  valid )
 
167
  {
 
168
    FT_Bytes  p = table;
 
169
    FT_UInt   SubstFormat;
 
170
 
 
171
 
 
172
    OTV_NAME_ENTER( "AlternateSubst" );
 
173
 
 
174
    OTV_LIMIT_CHECK( 2 );
 
175
    SubstFormat = FT_NEXT_USHORT( p );
 
176
 
 
177
    OTV_TRACE(( " (format %d)\n", SubstFormat ));
 
178
 
 
179
    switch ( SubstFormat )
 
180
    {
 
181
    case 1:
 
182
      valid->extra1 = valid->glyph_count;
 
183
      OTV_NEST2( AlternateSubstFormat1, AlternateSet );
 
184
      OTV_RUN( table, valid );
 
185
      break;
 
186
 
 
187
    default:
 
188
      FT_INVALID_FORMAT;
 
189
    }
 
190
 
 
191
    OTV_EXIT;
 
192
  }
 
193
 
 
194
 
 
195
  /*************************************************************************/
 
196
  /*************************************************************************/
 
197
  /*****                                                               *****/
 
198
  /*****                    GSUB LOOKUP TYPE 4                         *****/
 
199
  /*****                                                               *****/
 
200
  /*************************************************************************/
 
201
  /*************************************************************************/
 
202
 
 
203
#define LigatureFunc  otv_Ligature_validate
 
204
 
 
205
  /* uses valid->glyph_count */
 
206
 
 
207
  static void
 
208
  otv_Ligature_validate( FT_Bytes       table,
 
209
                         OTV_Validator  valid )
 
210
  {
 
211
    FT_Bytes  p = table;
 
212
    FT_UInt   LigatureGlyph, CompCount;
 
213
 
 
214
 
 
215
    OTV_ENTER;
 
216
 
 
217
    OTV_LIMIT_CHECK( 4 );
 
218
    LigatureGlyph = FT_NEXT_USHORT( p );
 
219
    if ( LigatureGlyph >= valid->glyph_count )
 
220
      FT_INVALID_DATA;
 
221
 
 
222
    CompCount = FT_NEXT_USHORT( p );
 
223
 
 
224
    OTV_TRACE(( " (CompCount = %d)\n", CompCount ));
 
225
 
 
226
    if ( CompCount == 0 )
 
227
      FT_INVALID_DATA;
 
228
 
 
229
    CompCount--;
 
230
 
 
231
    OTV_LIMIT_CHECK( CompCount * 2 );     /* Component */
 
232
 
 
233
    /* no need to check the Component glyph indices */
 
234
 
 
235
    OTV_EXIT;
 
236
  }
 
237
 
 
238
 
 
239
  static void
 
240
  otv_LigatureSubst_validate( FT_Bytes       table,
 
241
                              OTV_Validator  valid )
 
242
  {
 
243
    FT_Bytes  p = table;
 
244
    FT_UInt   SubstFormat;
 
245
 
 
246
 
 
247
    OTV_NAME_ENTER( "LigatureSubst" );
 
248
 
 
249
    OTV_LIMIT_CHECK( 2 );
 
250
    SubstFormat = FT_NEXT_USHORT( p );
 
251
 
 
252
    OTV_TRACE(( " (format %d)\n", SubstFormat ));
 
253
 
 
254
    switch ( SubstFormat )
 
255
    {
 
256
    case 1:
 
257
      OTV_NEST3( LigatureSubstFormat1, LigatureSet, Ligature );
 
258
      OTV_RUN( table, valid );
 
259
      break;
 
260
 
 
261
    default:
 
262
      FT_INVALID_FORMAT;
 
263
    }
 
264
 
 
265
    OTV_EXIT;
 
266
  }
 
267
 
 
268
 
 
269
  /*************************************************************************/
 
270
  /*************************************************************************/
 
271
  /*****                                                               *****/
 
272
  /*****                  GSUB LOOKUP TYPE 5                           *****/
 
273
  /*****                                                               *****/
 
274
  /*************************************************************************/
 
275
  /*************************************************************************/
 
276
 
 
277
  /* sets valid->extra1 (lookup count) */
 
278
 
 
279
  static void
 
280
  otv_ContextSubst_validate( FT_Bytes       table,
 
281
                             OTV_Validator  valid )
 
282
  {
 
283
    FT_Bytes  p = table;
 
284
    FT_UInt   SubstFormat;
 
285
 
 
286
 
 
287
    OTV_NAME_ENTER( "ContextSubst" );
 
288
 
 
289
    OTV_LIMIT_CHECK( 2 );
 
290
    SubstFormat = FT_NEXT_USHORT( p );
 
291
 
 
292
    OTV_TRACE(( " (format %d)\n", SubstFormat ));
 
293
 
 
294
    switch ( SubstFormat )
 
295
    {
 
296
    case 1:
 
297
      /* no need to check glyph indices/classes used as input for these */
 
298
      /* context rules since even invalid glyph indices/classes return  */
 
299
      /* meaningful results                                             */
 
300
 
 
301
      valid->extra1 = valid->lookup_count;
 
302
      OTV_NEST3( ContextSubstFormat1, SubRuleSet, SubRule );
 
303
      OTV_RUN( table, valid );
 
304
      break;
 
305
 
 
306
    case 2:
 
307
      /* no need to check glyph indices/classes used as input for these */
 
308
      /* context rules since even invalid glyph indices/classes return  */
 
309
      /* meaningful results                                             */
 
310
 
 
311
      OTV_NEST3( ContextSubstFormat2, SubClassSet, SubClassRule );
 
312
      OTV_RUN( table, valid );
 
313
      break;
 
314
 
 
315
    case 3:
 
316
      OTV_NEST1( ContextSubstFormat3 );
 
317
      OTV_RUN( table, valid );
 
318
      break;
 
319
 
 
320
    default:
 
321
      FT_INVALID_FORMAT;
 
322
    }
 
323
 
 
324
    OTV_EXIT;
 
325
  }
 
326
 
 
327
 
 
328
  /*************************************************************************/
 
329
  /*************************************************************************/
 
330
  /*****                                                               *****/
 
331
  /*****                    GSUB LOOKUP TYPE 6                         *****/
 
332
  /*****                                                               *****/
 
333
  /*************************************************************************/
 
334
  /*************************************************************************/
 
335
 
 
336
  /* sets valid->extra1 (lookup count)            */
 
337
 
 
338
  static void
 
339
  otv_ChainContextSubst_validate( FT_Bytes       table,
 
340
                                  OTV_Validator  valid )
 
341
  {
 
342
    FT_Bytes  p = table;
 
343
    FT_UInt   SubstFormat;
 
344
 
 
345
 
 
346
    OTV_NAME_ENTER( "ChainContextSubst" );
 
347
 
 
348
    OTV_LIMIT_CHECK( 2 );
 
349
    SubstFormat = FT_NEXT_USHORT( p );
 
350
 
 
351
    OTV_TRACE(( " (format %d)\n", SubstFormat ));
 
352
 
 
353
    switch ( SubstFormat )
 
354
    {
 
355
    case 1:
 
356
      /* no need to check glyph indices/classes used as input for these */
 
357
      /* context rules since even invalid glyph indices/classes return  */
 
358
      /* meaningful results                                             */
 
359
 
 
360
      valid->extra1 = valid->lookup_count;
 
361
      OTV_NEST3( ChainContextSubstFormat1,
 
362
                 ChainSubRuleSet, ChainSubRule );
 
363
      OTV_RUN( table, valid );
 
364
      break;
 
365
 
 
366
    case 2:
 
367
      /* no need to check glyph indices/classes used as input for these */
 
368
      /* context rules since even invalid glyph indices/classes return  */
 
369
      /* meaningful results                                             */
 
370
 
 
371
      OTV_NEST3( ChainContextSubstFormat2,
 
372
                 ChainSubClassSet, ChainSubClassRule );
 
373
      OTV_RUN( table, valid );
 
374
      break;
 
375
 
 
376
    case 3:
 
377
      OTV_NEST1( ChainContextSubstFormat3 );
 
378
      OTV_RUN( table, valid );
 
379
      break;
 
380
 
 
381
    default:
 
382
      FT_INVALID_FORMAT;
 
383
    }
 
384
 
 
385
    OTV_EXIT;
 
386
  }
 
387
 
 
388
 
 
389
  /*************************************************************************/
 
390
  /*************************************************************************/
 
391
  /*****                                                               *****/
 
392
  /*****                    GSUB LOOKUP TYPE 7                         *****/
 
393
  /*****                                                               *****/
 
394
  /*************************************************************************/
 
395
  /*************************************************************************/
 
396
 
 
397
  /* uses valid->type_funcs */
 
398
 
 
399
  static void
 
400
  otv_ExtensionSubst_validate( FT_Bytes       table,
 
401
                               OTV_Validator  valid )
 
402
  {
 
403
    FT_Bytes  p = table;
 
404
    FT_UInt   SubstFormat;
 
405
 
 
406
 
 
407
    OTV_NAME_ENTER( "ExtensionSubst" );
 
408
 
 
409
    OTV_LIMIT_CHECK( 2 );
 
410
    SubstFormat = FT_NEXT_USHORT( p );
 
411
 
 
412
    OTV_TRACE(( " (format %d)\n", SubstFormat ));
 
413
 
 
414
    switch ( SubstFormat )
 
415
    {
 
416
    case 1:     /* ExtensionSubstFormat1 */
 
417
      {
 
418
        FT_UInt            ExtensionLookupType;
 
419
        FT_ULong           ExtensionOffset;
 
420
        OTV_Validate_Func  validate;
 
421
 
 
422
 
 
423
        OTV_LIMIT_CHECK( 6 );
 
424
        ExtensionLookupType = FT_NEXT_USHORT( p );
 
425
        ExtensionOffset     = FT_NEXT_ULONG( p );
 
426
 
 
427
        if ( ExtensionLookupType == 0 ||
 
428
             ExtensionLookupType == 7 ||
 
429
             ExtensionLookupType > 8  )
 
430
          FT_INVALID_DATA;
 
431
 
 
432
        validate = valid->type_funcs[ExtensionLookupType - 1];
 
433
        validate( table + ExtensionOffset, valid );
 
434
      }
 
435
      break;
 
436
 
 
437
    default:
 
438
      FT_INVALID_FORMAT;
 
439
    }
 
440
 
 
441
    OTV_EXIT;
 
442
  }
 
443
 
 
444
 
 
445
  /*************************************************************************/
 
446
  /*************************************************************************/
 
447
  /*****                                                               *****/
 
448
  /*****                    GSUB LOOKUP TYPE 8                         *****/
 
449
  /*****                                                               *****/
 
450
  /*************************************************************************/
 
451
  /*************************************************************************/
 
452
 
 
453
  /* uses valid->glyph_count */
 
454
 
 
455
  static void
 
456
  otv_ReverseChainSingleSubst_validate( FT_Bytes       table,
 
457
                                        OTV_Validator  valid )
 
458
  {
 
459
    FT_Bytes  p = table, Coverage;
 
460
    FT_UInt   SubstFormat;
 
461
    FT_UInt   BacktrackGlyphCount, LookaheadGlyphCount, GlyphCount;
 
462
 
 
463
 
 
464
    OTV_NAME_ENTER( "ReverseChainSingleSubst" );
 
465
 
 
466
    OTV_LIMIT_CHECK( 2 );
 
467
    SubstFormat = FT_NEXT_USHORT( p );
 
468
 
 
469
    OTV_TRACE(( " (format %d)\n", SubstFormat ));
 
470
 
 
471
    switch ( SubstFormat )
 
472
    {
 
473
    case 1:     /* ReverseChainSingleSubstFormat1 */
 
474
      OTV_LIMIT_CHECK( 4 );
 
475
      Coverage            = table + FT_NEXT_USHORT( p );
 
476
      BacktrackGlyphCount = FT_NEXT_USHORT( p );
 
477
 
 
478
      OTV_TRACE(( " (BacktrackGlyphCount = %d)\n", BacktrackGlyphCount ));
 
479
 
 
480
      otv_Coverage_validate( Coverage, valid, -1 );
 
481
 
 
482
      OTV_LIMIT_CHECK( BacktrackGlyphCount * 2 + 2 );
 
483
 
 
484
      for ( ; BacktrackGlyphCount > 0; BacktrackGlyphCount-- )
 
485
        otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 );
 
486
 
 
487
      LookaheadGlyphCount = FT_NEXT_USHORT( p );
 
488
 
 
489
      OTV_TRACE(( " (LookaheadGlyphCount = %d)\n", LookaheadGlyphCount ));
 
490
 
 
491
      OTV_LIMIT_CHECK( LookaheadGlyphCount * 2 + 2 );
 
492
 
 
493
      for ( ; LookaheadGlyphCount > 0; LookaheadGlyphCount-- )
 
494
        otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 );
 
495
 
 
496
      GlyphCount = FT_NEXT_USHORT( p );
 
497
 
 
498
      OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount ));
 
499
 
 
500
      if ( GlyphCount != otv_Coverage_get_count( Coverage ) )
 
501
        FT_INVALID_DATA;
 
502
 
 
503
      OTV_LIMIT_CHECK( GlyphCount * 2 );
 
504
 
 
505
      /* Substitute */
 
506
      for ( ; GlyphCount > 0; GlyphCount-- )
 
507
        if ( FT_NEXT_USHORT( p ) >= valid->glyph_count )
 
508
          FT_INVALID_DATA;
 
509
 
 
510
      break;
 
511
 
 
512
    default:
 
513
      FT_INVALID_FORMAT;
 
514
    }
 
515
 
 
516
    OTV_EXIT;
 
517
  }
 
518
 
 
519
 
 
520
  static const OTV_Validate_Func  otv_gsub_validate_funcs[8] =
 
521
  {
 
522
    otv_SingleSubst_validate,
 
523
    otv_MultipleSubst_validate,
 
524
    otv_AlternateSubst_validate,
 
525
    otv_LigatureSubst_validate,
 
526
    otv_ContextSubst_validate,
 
527
    otv_ChainContextSubst_validate,
 
528
    otv_ExtensionSubst_validate,
 
529
    otv_ReverseChainSingleSubst_validate
 
530
  };
 
531
 
 
532
 
 
533
  /*************************************************************************/
 
534
  /*************************************************************************/
 
535
  /*****                                                               *****/
 
536
  /*****                          GSUB TABLE                           *****/
 
537
  /*****                                                               *****/
 
538
  /*************************************************************************/
 
539
  /*************************************************************************/
 
540
 
 
541
  /* sets valid->type_count  */
 
542
  /* sets valid->type_funcs  */
 
543
  /* sets valid->glyph_count */
 
544
 
 
545
  FT_LOCAL_DEF( void )
 
546
  otv_GSUB_validate( FT_Bytes      table,
 
547
                     FT_UInt       glyph_count,
 
548
                     FT_Validator  ftvalid )
 
549
  {
 
550
    OTV_ValidatorRec  validrec;
 
551
    OTV_Validator     valid = &validrec;
 
552
    FT_Bytes          p     = table;
 
553
    FT_UInt           ScriptList, FeatureList, LookupList;
 
554
 
 
555
 
 
556
    valid->root = ftvalid;
 
557
 
 
558
    FT_TRACE3(( "validating GSUB table\n" ));
 
559
    OTV_INIT;
 
560
 
 
561
    OTV_LIMIT_CHECK( 10 );
 
562
 
 
563
    if ( FT_NEXT_ULONG( p ) != 0x10000UL )      /* Version */
 
564
      FT_INVALID_FORMAT;
 
565
 
 
566
    ScriptList  = FT_NEXT_USHORT( p );
 
567
    FeatureList = FT_NEXT_USHORT( p );
 
568
    LookupList  = FT_NEXT_USHORT( p );
 
569
 
 
570
    valid->type_count  = 8;
 
571
    valid->type_funcs  = (OTV_Validate_Func*)otv_gsub_validate_funcs;
 
572
    valid->glyph_count = glyph_count;
 
573
 
 
574
    otv_LookupList_validate( table + LookupList,
 
575
                             valid );
 
576
    otv_FeatureList_validate( table + FeatureList, table + LookupList,
 
577
                              valid );
 
578
    otv_ScriptList_validate( table + ScriptList, table + FeatureList,
 
579
                             valid );
 
580
 
 
581
    FT_TRACE4(( "\n" ));
 
582
  }
 
583
 
 
584
 
 
585
/* END */