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

« back to all changes in this revision

Viewing changes to tests/freetype/src/otvalid/otvcommn.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
/*  otvcommn.c                                                             */
 
4
/*                                                                         */
 
5
/*    OpenType common tables validation (body).                            */
 
6
/*                                                                         */
 
7
/*  Copyright 2004, 2005, 2006, 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 "otvcommn.h"
 
20
 
 
21
 
 
22
  /*************************************************************************/
 
23
  /*                                                                       */
 
24
  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
 
25
  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
 
26
  /* messages during execution.                                            */
 
27
  /*                                                                       */
 
28
#undef  FT_COMPONENT
 
29
#define FT_COMPONENT  trace_otvcommon
 
30
 
 
31
 
 
32
  /*************************************************************************/
 
33
  /*************************************************************************/
 
34
  /*****                                                               *****/
 
35
  /*****                       COVERAGE TABLE                          *****/
 
36
  /*****                                                               *****/
 
37
  /*************************************************************************/
 
38
  /*************************************************************************/
 
39
 
 
40
  FT_LOCAL_DEF( void )
 
41
  otv_Coverage_validate( FT_Bytes       table,
 
42
                         OTV_Validator  valid,
 
43
                         FT_Int         expected_count )
 
44
  {
 
45
    FT_Bytes  p = table;
 
46
    FT_UInt   CoverageFormat;
 
47
    FT_UInt   total = 0;
 
48
 
 
49
 
 
50
    OTV_NAME_ENTER( "Coverage" );
 
51
 
 
52
    OTV_LIMIT_CHECK( 4 );
 
53
    CoverageFormat = FT_NEXT_USHORT( p );
 
54
 
 
55
    OTV_TRACE(( " (format %d)\n", CoverageFormat ));
 
56
 
 
57
    switch ( CoverageFormat )
 
58
    {
 
59
    case 1:     /* CoverageFormat1 */
 
60
      {
 
61
        FT_UInt  GlyphCount;
 
62
        FT_UInt  i;
 
63
 
 
64
 
 
65
        GlyphCount = FT_NEXT_USHORT( p );
 
66
 
 
67
        OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount ));
 
68
 
 
69
        OTV_LIMIT_CHECK( GlyphCount * 2 );        /* GlyphArray */
 
70
 
 
71
        for ( i = 0; i < GlyphCount; ++i )
 
72
        {
 
73
          FT_UInt  gid;
 
74
 
 
75
 
 
76
          gid = FT_NEXT_USHORT( p );
 
77
          if ( gid >= valid->glyph_count )
 
78
            FT_INVALID_GLYPH_ID;
 
79
        }
 
80
 
 
81
        total = GlyphCount;
 
82
      }
 
83
      break;
 
84
 
 
85
    case 2:     /* CoverageFormat2 */
 
86
      {
 
87
        FT_UInt  n, RangeCount;
 
88
        FT_UInt  Start, End, StartCoverageIndex, last = 0;
 
89
 
 
90
 
 
91
        RangeCount = FT_NEXT_USHORT( p );
 
92
 
 
93
        OTV_TRACE(( " (RangeCount = %d)\n", RangeCount ));
 
94
 
 
95
        OTV_LIMIT_CHECK( RangeCount * 6 );
 
96
 
 
97
        /* RangeRecord */
 
98
        for ( n = 0; n < RangeCount; n++ )
 
99
        {
 
100
          Start              = FT_NEXT_USHORT( p );
 
101
          End                = FT_NEXT_USHORT( p );
 
102
          StartCoverageIndex = FT_NEXT_USHORT( p );
 
103
 
 
104
          if ( Start > End || StartCoverageIndex != total )
 
105
            FT_INVALID_DATA;
 
106
 
 
107
          if ( End >= valid->glyph_count )
 
108
            FT_INVALID_GLYPH_ID;
 
109
 
 
110
          if ( n > 0 && Start <= last )
 
111
            FT_INVALID_DATA;
 
112
 
 
113
          total += End - Start + 1;
 
114
          last   = End;
 
115
        }
 
116
      }
 
117
      break;
 
118
 
 
119
    default:
 
120
      FT_INVALID_FORMAT;
 
121
    }
 
122
 
 
123
    /* Generally, a coverage table offset has an associated count field.  */
 
124
    /* The number of glyphs in the table should match this field.  If     */
 
125
    /* there is no associated count, a value of -1 tells us not to check. */
 
126
    if ( expected_count != -1 && (FT_UInt)expected_count != total )
 
127
      FT_INVALID_DATA;
 
128
 
 
129
    OTV_EXIT;
 
130
  }
 
131
 
 
132
 
 
133
  FT_LOCAL_DEF( FT_UInt )
 
134
  otv_Coverage_get_first( FT_Bytes  table )
 
135
  {
 
136
    FT_Bytes  p = table;
 
137
 
 
138
 
 
139
    p += 4;     /* skip CoverageFormat and Glyph/RangeCount */
 
140
 
 
141
    return FT_NEXT_USHORT( p );
 
142
  }
 
143
 
 
144
 
 
145
  FT_LOCAL_DEF( FT_UInt )
 
146
  otv_Coverage_get_last( FT_Bytes  table )
 
147
  {
 
148
    FT_Bytes  p = table;
 
149
    FT_UInt   CoverageFormat = FT_NEXT_USHORT( p );
 
150
    FT_UInt   count          = FT_NEXT_USHORT( p );     /* Glyph/RangeCount */
 
151
    FT_UInt   result = 0;
 
152
 
 
153
 
 
154
    switch ( CoverageFormat )
 
155
    {
 
156
    case 1:
 
157
      p += ( count - 1 ) * 2;
 
158
      result = FT_NEXT_USHORT( p );
 
159
      break;
 
160
 
 
161
    case 2:
 
162
      p += ( count - 1 ) * 6 + 2;
 
163
      result = FT_NEXT_USHORT( p );
 
164
      break;
 
165
 
 
166
    default:
 
167
      ;
 
168
    }
 
169
 
 
170
    return result;
 
171
  }
 
172
 
 
173
 
 
174
  FT_LOCAL_DEF( FT_UInt )
 
175
  otv_Coverage_get_count( FT_Bytes  table )
 
176
  {
 
177
    FT_Bytes  p              = table;
 
178
    FT_UInt   CoverageFormat = FT_NEXT_USHORT( p );
 
179
    FT_UInt   count          = FT_NEXT_USHORT( p );     /* Glyph/RangeCount */
 
180
    FT_UInt   result         = 0;
 
181
 
 
182
 
 
183
    switch ( CoverageFormat )
 
184
    {
 
185
    case 1:
 
186
      return count;
 
187
 
 
188
    case 2:
 
189
      {
 
190
        FT_UInt  Start, End;
 
191
 
 
192
 
 
193
        for ( ; count > 0; count-- )
 
194
        {
 
195
          Start = FT_NEXT_USHORT( p );
 
196
          End   = FT_NEXT_USHORT( p );
 
197
          p    += 2;                    /* skip StartCoverageIndex */
 
198
 
 
199
          result += End - Start + 1;
 
200
        }
 
201
      }
 
202
      break;
 
203
 
 
204
    default:
 
205
      ;
 
206
    }
 
207
 
 
208
    return result;
 
209
  }
 
210
 
 
211
 
 
212
  /*************************************************************************/
 
213
  /*************************************************************************/
 
214
  /*****                                                               *****/
 
215
  /*****                   CLASS DEFINITION TABLE                      *****/
 
216
  /*****                                                               *****/
 
217
  /*************************************************************************/
 
218
  /*************************************************************************/
 
219
 
 
220
  FT_LOCAL_DEF( void )
 
221
  otv_ClassDef_validate( FT_Bytes       table,
 
222
                         OTV_Validator  valid )
 
223
  {
 
224
    FT_Bytes  p = table;
 
225
    FT_UInt   ClassFormat;
 
226
 
 
227
 
 
228
    OTV_NAME_ENTER( "ClassDef" );
 
229
 
 
230
    OTV_LIMIT_CHECK( 4 );
 
231
    ClassFormat = FT_NEXT_USHORT( p );
 
232
 
 
233
    OTV_TRACE(( " (format %d)\n", ClassFormat ));
 
234
 
 
235
    switch ( ClassFormat )
 
236
    {
 
237
    case 1:     /* ClassDefFormat1 */
 
238
      {
 
239
        FT_UInt  StartGlyph;
 
240
        FT_UInt  GlyphCount;
 
241
 
 
242
 
 
243
        OTV_LIMIT_CHECK( 4 );
 
244
 
 
245
        StartGlyph = FT_NEXT_USHORT( p );
 
246
        GlyphCount = FT_NEXT_USHORT( p );
 
247
 
 
248
        OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount ));
 
249
 
 
250
        OTV_LIMIT_CHECK( GlyphCount * 2 );    /* ClassValueArray */
 
251
 
 
252
        if ( StartGlyph + GlyphCount - 1 >= valid->glyph_count )
 
253
          FT_INVALID_GLYPH_ID;
 
254
      }
 
255
      break;
 
256
 
 
257
    case 2:     /* ClassDefFormat2 */
 
258
      {
 
259
        FT_UInt  n, ClassRangeCount;
 
260
        FT_UInt  Start, End, last = 0;
 
261
 
 
262
 
 
263
        ClassRangeCount = FT_NEXT_USHORT( p );
 
264
 
 
265
        OTV_TRACE(( " (ClassRangeCount = %d)\n", ClassRangeCount ));
 
266
 
 
267
        OTV_LIMIT_CHECK( ClassRangeCount * 6 );
 
268
 
 
269
        /* ClassRangeRecord */
 
270
        for ( n = 0; n < ClassRangeCount; n++ )
 
271
        {
 
272
          Start = FT_NEXT_USHORT( p );
 
273
          End   = FT_NEXT_USHORT( p );
 
274
          p    += 2;                        /* skip Class */
 
275
 
 
276
          if ( Start > End || ( n > 0 && Start <= last ) )
 
277
            FT_INVALID_DATA;
 
278
 
 
279
          if ( End >= valid->glyph_count )
 
280
            FT_INVALID_GLYPH_ID;
 
281
 
 
282
          last = End;
 
283
        }
 
284
      }
 
285
      break;
 
286
 
 
287
    default:
 
288
      FT_INVALID_FORMAT;
 
289
    }
 
290
 
 
291
    /* no need to check glyph indices used as input to class definition   */
 
292
    /* tables since even invalid glyph indices return a meaningful result */
 
293
 
 
294
    OTV_EXIT;
 
295
  }
 
296
 
 
297
 
 
298
  /*************************************************************************/
 
299
  /*************************************************************************/
 
300
  /*****                                                               *****/
 
301
  /*****                      DEVICE TABLE                             *****/
 
302
  /*****                                                               *****/
 
303
  /*************************************************************************/
 
304
  /*************************************************************************/
 
305
 
 
306
  FT_LOCAL_DEF( void )
 
307
  otv_Device_validate( FT_Bytes       table,
 
308
                       OTV_Validator  valid )
 
309
  {
 
310
    FT_Bytes  p = table;
 
311
    FT_UInt   StartSize, EndSize, DeltaFormat, count;
 
312
 
 
313
 
 
314
    OTV_NAME_ENTER( "Device" );
 
315
 
 
316
    OTV_LIMIT_CHECK( 8 );
 
317
    StartSize   = FT_NEXT_USHORT( p );
 
318
    EndSize     = FT_NEXT_USHORT( p );
 
319
    DeltaFormat = FT_NEXT_USHORT( p );
 
320
 
 
321
    if ( DeltaFormat < 1 || DeltaFormat > 3 )
 
322
      FT_INVALID_FORMAT;
 
323
 
 
324
    if ( EndSize < StartSize )
 
325
      FT_INVALID_DATA;
 
326
 
 
327
    count = EndSize - StartSize + 1;
 
328
    OTV_LIMIT_CHECK( ( 1 << DeltaFormat ) * count / 8 );  /* DeltaValue */
 
329
 
 
330
    OTV_EXIT;
 
331
  }
 
332
 
 
333
 
 
334
  /*************************************************************************/
 
335
  /*************************************************************************/
 
336
  /*****                                                               *****/
 
337
  /*****                         LOOKUPS                               *****/
 
338
  /*****                                                               *****/
 
339
  /*************************************************************************/
 
340
  /*************************************************************************/
 
341
 
 
342
  /* uses valid->type_count */
 
343
  /* uses valid->type_funcs */
 
344
 
 
345
  FT_LOCAL_DEF( void )
 
346
  otv_Lookup_validate( FT_Bytes       table,
 
347
                       OTV_Validator  valid )
 
348
  {
 
349
    FT_Bytes           p = table;
 
350
    FT_UInt            LookupType, SubTableCount;
 
351
    OTV_Validate_Func  validate;
 
352
 
 
353
 
 
354
    OTV_NAME_ENTER( "Lookup" );
 
355
 
 
356
    OTV_LIMIT_CHECK( 6 );
 
357
    LookupType    = FT_NEXT_USHORT( p );
 
358
    p            += 2;                      /* skip LookupFlag */
 
359
    SubTableCount = FT_NEXT_USHORT( p );
 
360
 
 
361
    OTV_TRACE(( " (type %d)\n", LookupType ));
 
362
 
 
363
    if ( LookupType == 0 || LookupType > valid->type_count )
 
364
      FT_INVALID_DATA;
 
365
 
 
366
    validate = valid->type_funcs[LookupType - 1];
 
367
 
 
368
    OTV_TRACE(( " (SubTableCount = %d)\n", SubTableCount ));
 
369
 
 
370
    OTV_LIMIT_CHECK( SubTableCount * 2 );
 
371
 
 
372
    /* SubTable */
 
373
    for ( ; SubTableCount > 0; SubTableCount-- )
 
374
      validate( table + FT_NEXT_USHORT( p ), valid );
 
375
 
 
376
    OTV_EXIT;
 
377
  }
 
378
 
 
379
 
 
380
  /* uses valid->lookup_count */
 
381
 
 
382
  FT_LOCAL_DEF( void )
 
383
  otv_LookupList_validate( FT_Bytes       table,
 
384
                           OTV_Validator  valid )
 
385
  {
 
386
    FT_Bytes  p = table;
 
387
    FT_UInt   LookupCount;
 
388
 
 
389
 
 
390
    OTV_NAME_ENTER( "LookupList" );
 
391
 
 
392
    OTV_LIMIT_CHECK( 2 );
 
393
    LookupCount = FT_NEXT_USHORT( p );
 
394
 
 
395
    OTV_TRACE(( " (LookupCount = %d)\n", LookupCount ));
 
396
 
 
397
    OTV_LIMIT_CHECK( LookupCount * 2 );
 
398
 
 
399
    valid->lookup_count = LookupCount;
 
400
 
 
401
    /* Lookup */
 
402
    for ( ; LookupCount > 0; LookupCount-- )
 
403
      otv_Lookup_validate( table + FT_NEXT_USHORT( p ), valid );
 
404
 
 
405
    OTV_EXIT;
 
406
  }
 
407
 
 
408
 
 
409
  static FT_UInt
 
410
  otv_LookupList_get_count( FT_Bytes  table )
 
411
  {
 
412
    return FT_NEXT_USHORT( table );
 
413
  }
 
414
 
 
415
 
 
416
  /*************************************************************************/
 
417
  /*************************************************************************/
 
418
  /*****                                                               *****/
 
419
  /*****                        FEATURES                               *****/
 
420
  /*****                                                               *****/
 
421
  /*************************************************************************/
 
422
  /*************************************************************************/
 
423
 
 
424
  /* uses valid->lookup_count */
 
425
 
 
426
  FT_LOCAL_DEF( void )
 
427
  otv_Feature_validate( FT_Bytes       table,
 
428
                        OTV_Validator  valid )
 
429
  {
 
430
    FT_Bytes  p = table;
 
431
    FT_UInt   LookupCount;
 
432
 
 
433
 
 
434
    OTV_NAME_ENTER( "Feature" );
 
435
 
 
436
    OTV_LIMIT_CHECK( 4 );
 
437
    p           += 2;                   /* skip FeatureParams (unused) */
 
438
    LookupCount  = FT_NEXT_USHORT( p );
 
439
 
 
440
    OTV_TRACE(( " (LookupCount = %d)\n", LookupCount ));
 
441
 
 
442
    OTV_LIMIT_CHECK( LookupCount * 2 );
 
443
 
 
444
    /* LookupListIndex */
 
445
    for ( ; LookupCount > 0; LookupCount-- )
 
446
      if ( FT_NEXT_USHORT( p ) >= valid->lookup_count )
 
447
        FT_INVALID_DATA;
 
448
 
 
449
    OTV_EXIT;
 
450
  }
 
451
 
 
452
 
 
453
  static FT_UInt
 
454
  otv_Feature_get_count( FT_Bytes  table )
 
455
  {
 
456
    return FT_NEXT_USHORT( table );
 
457
  }
 
458
 
 
459
 
 
460
  /* sets valid->lookup_count */
 
461
 
 
462
  FT_LOCAL_DEF( void )
 
463
  otv_FeatureList_validate( FT_Bytes       table,
 
464
                            FT_Bytes       lookups,
 
465
                            OTV_Validator  valid )
 
466
  {
 
467
    FT_Bytes  p = table;
 
468
    FT_UInt   FeatureCount;
 
469
 
 
470
 
 
471
    OTV_NAME_ENTER( "FeatureList" );
 
472
 
 
473
    OTV_LIMIT_CHECK( 2 );
 
474
    FeatureCount = FT_NEXT_USHORT( p );
 
475
 
 
476
    OTV_TRACE(( " (FeatureCount = %d)\n", FeatureCount ));
 
477
 
 
478
    OTV_LIMIT_CHECK( FeatureCount * 2 );
 
479
 
 
480
    valid->lookup_count = otv_LookupList_get_count( lookups );
 
481
 
 
482
    /* FeatureRecord */
 
483
    for ( ; FeatureCount > 0; FeatureCount-- )
 
484
    {
 
485
      p += 4;       /* skip FeatureTag */
 
486
 
 
487
      /* Feature */
 
488
      otv_Feature_validate( table + FT_NEXT_USHORT( p ), valid );
 
489
    }
 
490
 
 
491
    OTV_EXIT;
 
492
  }
 
493
 
 
494
 
 
495
  /*************************************************************************/
 
496
  /*************************************************************************/
 
497
  /*****                                                               *****/
 
498
  /*****                       LANGUAGE SYSTEM                         *****/
 
499
  /*****                                                               *****/
 
500
  /*************************************************************************/
 
501
  /*************************************************************************/
 
502
 
 
503
 
 
504
  /* uses valid->extra1 (number of features) */
 
505
 
 
506
  FT_LOCAL_DEF( void )
 
507
  otv_LangSys_validate( FT_Bytes       table,
 
508
                        OTV_Validator  valid )
 
509
  {
 
510
    FT_Bytes  p = table;
 
511
    FT_UInt   ReqFeatureIndex;
 
512
    FT_UInt   FeatureCount;
 
513
 
 
514
 
 
515
    OTV_NAME_ENTER( "LangSys" );
 
516
 
 
517
    OTV_LIMIT_CHECK( 6 );
 
518
    p              += 2;                    /* skip LookupOrder (unused) */
 
519
    ReqFeatureIndex = FT_NEXT_USHORT( p );
 
520
    FeatureCount    = FT_NEXT_USHORT( p );
 
521
 
 
522
    OTV_TRACE(( " (ReqFeatureIndex = %d)\n", ReqFeatureIndex ));
 
523
    OTV_TRACE(( " (FeatureCount = %d)\n",    FeatureCount    ));
 
524
 
 
525
    if ( ReqFeatureIndex != 0xFFFFU && ReqFeatureIndex >= valid->extra1 )
 
526
      FT_INVALID_DATA;
 
527
 
 
528
    OTV_LIMIT_CHECK( FeatureCount * 2 );
 
529
 
 
530
    /* FeatureIndex */
 
531
    for ( ; FeatureCount > 0; FeatureCount-- )
 
532
      if ( FT_NEXT_USHORT( p ) >= valid->extra1 )
 
533
        FT_INVALID_DATA;
 
534
 
 
535
    OTV_EXIT;
 
536
  }
 
537
 
 
538
 
 
539
  /*************************************************************************/
 
540
  /*************************************************************************/
 
541
  /*****                                                               *****/
 
542
  /*****                           SCRIPTS                             *****/
 
543
  /*****                                                               *****/
 
544
  /*************************************************************************/
 
545
  /*************************************************************************/
 
546
 
 
547
  FT_LOCAL_DEF( void )
 
548
  otv_Script_validate( FT_Bytes       table,
 
549
                       OTV_Validator  valid )
 
550
  {
 
551
    FT_UInt   DefaultLangSys, LangSysCount;
 
552
    FT_Bytes  p = table;
 
553
 
 
554
 
 
555
    OTV_NAME_ENTER( "Script" );
 
556
 
 
557
    OTV_LIMIT_CHECK( 4 );
 
558
    DefaultLangSys = FT_NEXT_USHORT( p );
 
559
    LangSysCount   = FT_NEXT_USHORT( p );
 
560
 
 
561
    OTV_TRACE(( " (LangSysCount = %d)\n", LangSysCount ));
 
562
 
 
563
    if ( DefaultLangSys != 0 )
 
564
      otv_LangSys_validate( table + DefaultLangSys, valid );
 
565
 
 
566
    OTV_LIMIT_CHECK( LangSysCount * 6 );
 
567
 
 
568
    /* LangSysRecord */
 
569
    for ( ; LangSysCount > 0; LangSysCount-- )
 
570
    {
 
571
      p += 4;       /* skip LangSysTag */
 
572
 
 
573
      /* LangSys */
 
574
      otv_LangSys_validate( table + FT_NEXT_USHORT( p ), valid );
 
575
    }
 
576
 
 
577
    OTV_EXIT;
 
578
  }
 
579
 
 
580
 
 
581
  /* sets valid->extra1 (number of features) */
 
582
 
 
583
  FT_LOCAL_DEF( void )
 
584
  otv_ScriptList_validate( FT_Bytes       table,
 
585
                           FT_Bytes       features,
 
586
                           OTV_Validator  valid )
 
587
  {
 
588
    FT_UInt   ScriptCount;
 
589
    FT_Bytes  p = table;
 
590
 
 
591
 
 
592
    OTV_NAME_ENTER( "ScriptList" );
 
593
 
 
594
    OTV_LIMIT_CHECK( 2 );
 
595
    ScriptCount = FT_NEXT_USHORT( p );
 
596
 
 
597
    OTV_TRACE(( " (ScriptCount = %d)\n", ScriptCount ));
 
598
 
 
599
    OTV_LIMIT_CHECK( ScriptCount * 6 );
 
600
 
 
601
    valid->extra1 = otv_Feature_get_count( features );
 
602
 
 
603
    /* ScriptRecord */
 
604
    for ( ; ScriptCount > 0; ScriptCount-- )
 
605
    {
 
606
      p += 4;       /* skip ScriptTag */
 
607
 
 
608
      otv_Script_validate( table + FT_NEXT_USHORT( p ), valid ); /* Script */
 
609
    }
 
610
 
 
611
    OTV_EXIT;
 
612
  }
 
613
 
 
614
 
 
615
  /*************************************************************************/
 
616
  /*************************************************************************/
 
617
  /*****                                                               *****/
 
618
  /*****                      UTILITY FUNCTIONS                        *****/
 
619
  /*****                                                               *****/
 
620
  /*************************************************************************/
 
621
  /*************************************************************************/
 
622
 
 
623
  /*
 
624
     u:   uint16
 
625
     ux:  unit16 [x]
 
626
 
 
627
     s:   struct
 
628
     sx:  struct [x]
 
629
     sxy: struct [x], using external y count
 
630
 
 
631
     x:   uint16 x
 
632
 
 
633
     C:   Coverage
 
634
 
 
635
     O:   Offset
 
636
     On:  Offset (NULL)
 
637
     Ox:  Offset [x]
 
638
     Onx: Offset (NULL) [x]
 
639
  */
 
640
 
 
641
  FT_LOCAL_DEF( void )
 
642
  otv_x_Ox( FT_Bytes       table,
 
643
            OTV_Validator  valid )
 
644
  {
 
645
    FT_Bytes           p = table;
 
646
    FT_UInt            Count;
 
647
    OTV_Validate_Func  func;
 
648
 
 
649
 
 
650
    OTV_ENTER;
 
651
 
 
652
    OTV_LIMIT_CHECK( 2 );
 
653
    Count = FT_NEXT_USHORT( p );
 
654
 
 
655
    OTV_TRACE(( " (Count = %d)\n", Count ));
 
656
 
 
657
    OTV_LIMIT_CHECK( Count * 2 );
 
658
 
 
659
    valid->nesting_level++;
 
660
    func = valid->func[valid->nesting_level];
 
661
 
 
662
    for ( ; Count > 0; Count-- )
 
663
      func( table + FT_NEXT_USHORT( p ), valid );
 
664
 
 
665
    valid->nesting_level--;
 
666
 
 
667
    OTV_EXIT;
 
668
  }
 
669
 
 
670
 
 
671
  FT_LOCAL_DEF( void )
 
672
  otv_u_C_x_Ox( FT_Bytes       table,
 
673
                OTV_Validator  valid )
 
674
  {
 
675
    FT_Bytes           p = table;
 
676
    FT_UInt            Count, Coverage;
 
677
    OTV_Validate_Func  func;
 
678
 
 
679
 
 
680
    OTV_ENTER;
 
681
 
 
682
    p += 2;     /* skip Format */
 
683
 
 
684
    OTV_LIMIT_CHECK( 4 );
 
685
    Coverage = FT_NEXT_USHORT( p );
 
686
    Count    = FT_NEXT_USHORT( p );
 
687
 
 
688
    OTV_TRACE(( " (Count = %d)\n", Count ));
 
689
 
 
690
    otv_Coverage_validate( table + Coverage, valid, Count );
 
691
 
 
692
    OTV_LIMIT_CHECK( Count * 2 );
 
693
 
 
694
    valid->nesting_level++;
 
695
    func = valid->func[valid->nesting_level];
 
696
 
 
697
    for ( ; Count > 0; Count-- )
 
698
      func( table + FT_NEXT_USHORT( p ), valid );
 
699
 
 
700
    valid->nesting_level--;
 
701
 
 
702
    OTV_EXIT;
 
703
  }
 
704
 
 
705
 
 
706
  /* uses valid->extra1 (if > 0: array value limit) */
 
707
 
 
708
  FT_LOCAL_DEF( void )
 
709
  otv_x_ux( FT_Bytes       table,
 
710
            OTV_Validator  valid )
 
711
  {
 
712
    FT_Bytes  p = table;
 
713
    FT_UInt   Count;
 
714
 
 
715
 
 
716
    OTV_ENTER;
 
717
 
 
718
    OTV_LIMIT_CHECK( 2 );
 
719
    Count = FT_NEXT_USHORT( p );
 
720
 
 
721
    OTV_TRACE(( " (Count = %d)\n", Count ));
 
722
 
 
723
    OTV_LIMIT_CHECK( Count * 2 );
 
724
 
 
725
    if ( valid->extra1 )
 
726
    {
 
727
      for ( ; Count > 0; Count-- )
 
728
        if ( FT_NEXT_USHORT( p ) >= valid->extra1 )
 
729
          FT_INVALID_DATA;
 
730
    }
 
731
 
 
732
    OTV_EXIT;
 
733
  }
 
734
 
 
735
 
 
736
  /* `ux' in the function's name is not really correct since only x-1 */
 
737
  /* elements are tested                                              */
 
738
 
 
739
  /* uses valid->extra1 (array value limit) */
 
740
 
 
741
  FT_LOCAL_DEF( void )
 
742
  otv_x_y_ux_sy( FT_Bytes       table,
 
743
                 OTV_Validator  valid )
 
744
  {
 
745
    FT_Bytes  p = table;
 
746
    FT_UInt   Count1, Count2;
 
747
 
 
748
 
 
749
    OTV_ENTER;
 
750
 
 
751
    OTV_LIMIT_CHECK( 4 );
 
752
    Count1 = FT_NEXT_USHORT( p );
 
753
    Count2 = FT_NEXT_USHORT( p );
 
754
 
 
755
    OTV_TRACE(( " (Count1 = %d)\n", Count1 ));
 
756
    OTV_TRACE(( " (Count2 = %d)\n", Count2 ));
 
757
 
 
758
    if ( Count1 == 0 )
 
759
      FT_INVALID_DATA;
 
760
 
 
761
    OTV_LIMIT_CHECK( ( Count1 - 1 ) * 2 + Count2 * 4 );
 
762
    p += ( Count1 - 1 ) * 2;
 
763
 
 
764
    for ( ; Count2 > 0; Count2-- )
 
765
    {
 
766
      if ( FT_NEXT_USHORT( p ) >= Count1 )
 
767
        FT_INVALID_DATA;
 
768
 
 
769
      if ( FT_NEXT_USHORT( p ) >= valid->extra1 )
 
770
        FT_INVALID_DATA;
 
771
    }
 
772
 
 
773
    OTV_EXIT;
 
774
  }
 
775
 
 
776
 
 
777
  /* `uy' in the function's name is not really correct since only y-1 */
 
778
  /* elements are tested                                              */
 
779
 
 
780
  /* uses valid->extra1 (array value limit) */
 
781
 
 
782
  FT_LOCAL_DEF( void )
 
783
  otv_x_ux_y_uy_z_uz_p_sp( FT_Bytes       table,
 
784
                           OTV_Validator  valid )
 
785
  {
 
786
    FT_Bytes  p = table;
 
787
    FT_UInt   BacktrackCount, InputCount, LookaheadCount;
 
788
    FT_UInt   Count;
 
789
 
 
790
 
 
791
    OTV_ENTER;
 
792
 
 
793
    OTV_LIMIT_CHECK( 2 );
 
794
    BacktrackCount = FT_NEXT_USHORT( p );
 
795
 
 
796
    OTV_TRACE(( " (BacktrackCount = %d)\n", BacktrackCount ));
 
797
 
 
798
    OTV_LIMIT_CHECK( BacktrackCount * 2 + 2 );
 
799
    p += BacktrackCount * 2;
 
800
 
 
801
    InputCount = FT_NEXT_USHORT( p );
 
802
    if ( InputCount == 0 )
 
803
      FT_INVALID_DATA;
 
804
 
 
805
    OTV_TRACE(( " (InputCount = %d)\n", InputCount ));
 
806
 
 
807
    OTV_LIMIT_CHECK( InputCount * 2 );
 
808
    p += ( InputCount - 1 ) * 2;
 
809
 
 
810
    LookaheadCount = FT_NEXT_USHORT( p );
 
811
 
 
812
    OTV_TRACE(( " (LookaheadCount = %d)\n", LookaheadCount ));
 
813
 
 
814
    OTV_LIMIT_CHECK( LookaheadCount * 2 + 2 );
 
815
    p += LookaheadCount * 2;
 
816
 
 
817
    Count = FT_NEXT_USHORT( p );
 
818
 
 
819
    OTV_TRACE(( " (Count = %d)\n", Count ));
 
820
 
 
821
    OTV_LIMIT_CHECK( Count * 4 );
 
822
 
 
823
    for ( ; Count > 0; Count-- )
 
824
    {
 
825
      if ( FT_NEXT_USHORT( p ) >= InputCount )
 
826
        FT_INVALID_DATA;
 
827
 
 
828
      if ( FT_NEXT_USHORT( p ) >= valid->extra1 )
 
829
        FT_INVALID_DATA;
 
830
    }
 
831
 
 
832
    OTV_EXIT;
 
833
  }
 
834
 
 
835
 
 
836
  /* sets valid->extra1 (valid->lookup_count) */
 
837
 
 
838
  FT_LOCAL_DEF( void )
 
839
  otv_u_O_O_x_Onx( FT_Bytes       table,
 
840
                   OTV_Validator  valid )
 
841
  {
 
842
    FT_Bytes           p = table;
 
843
    FT_UInt            Coverage, ClassDef, ClassSetCount;
 
844
    OTV_Validate_Func  func;
 
845
 
 
846
 
 
847
    OTV_ENTER;
 
848
 
 
849
    p += 2;     /* skip Format */
 
850
 
 
851
    OTV_LIMIT_CHECK( 6 );
 
852
    Coverage      = FT_NEXT_USHORT( p );
 
853
    ClassDef      = FT_NEXT_USHORT( p );
 
854
    ClassSetCount = FT_NEXT_USHORT( p );
 
855
 
 
856
    OTV_TRACE(( " (ClassSetCount = %d)\n", ClassSetCount ));
 
857
 
 
858
    otv_Coverage_validate( table + Coverage, valid, -1 );
 
859
    otv_ClassDef_validate( table + ClassDef, valid );
 
860
 
 
861
    OTV_LIMIT_CHECK( ClassSetCount * 2 );
 
862
 
 
863
    valid->nesting_level++;
 
864
    func          = valid->func[valid->nesting_level];
 
865
    valid->extra1 = valid->lookup_count;
 
866
 
 
867
    for ( ; ClassSetCount > 0; ClassSetCount-- )
 
868
    {
 
869
      FT_UInt  offset = FT_NEXT_USHORT( p );
 
870
 
 
871
 
 
872
      if ( offset )
 
873
        func( table + offset, valid );
 
874
    }
 
875
 
 
876
    valid->nesting_level--;
 
877
 
 
878
    OTV_EXIT;
 
879
  }
 
880
 
 
881
 
 
882
  /* uses valid->lookup_count */
 
883
 
 
884
  FT_LOCAL_DEF( void )
 
885
  otv_u_x_y_Ox_sy( FT_Bytes       table,
 
886
                   OTV_Validator  valid )
 
887
  {
 
888
    FT_Bytes  p = table;
 
889
    FT_UInt   GlyphCount, Count, count1;
 
890
 
 
891
 
 
892
    OTV_ENTER;
 
893
 
 
894
    p += 2;     /* skip Format */
 
895
 
 
896
    OTV_LIMIT_CHECK( 4 );
 
897
    GlyphCount = FT_NEXT_USHORT( p );
 
898
    Count      = FT_NEXT_USHORT( p );
 
899
 
 
900
    OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount ));
 
901
    OTV_TRACE(( " (Count = %d)\n",      Count      ));
 
902
 
 
903
    OTV_LIMIT_CHECK( GlyphCount * 2 + Count * 4 );
 
904
 
 
905
    for ( count1 = GlyphCount; count1 > 0; count1-- )
 
906
      otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 );
 
907
 
 
908
    for ( ; Count > 0; Count-- )
 
909
    {
 
910
      if ( FT_NEXT_USHORT( p ) >= GlyphCount )
 
911
        FT_INVALID_DATA;
 
912
 
 
913
      if ( FT_NEXT_USHORT( p ) >= valid->lookup_count )
 
914
        FT_INVALID_DATA;
 
915
    }
 
916
 
 
917
    OTV_EXIT;
 
918
  }
 
919
 
 
920
 
 
921
  /* sets valid->extra1 (valid->lookup_count)    */
 
922
 
 
923
  FT_LOCAL_DEF( void )
 
924
  otv_u_O_O_O_O_x_Onx( FT_Bytes       table,
 
925
                       OTV_Validator  valid )
 
926
  {
 
927
    FT_Bytes           p = table;
 
928
    FT_UInt            Coverage;
 
929
    FT_UInt            BacktrackClassDef, InputClassDef, LookaheadClassDef;
 
930
    FT_UInt            ChainClassSetCount;
 
931
    OTV_Validate_Func  func;
 
932
 
 
933
 
 
934
    OTV_ENTER;
 
935
 
 
936
    p += 2;     /* skip Format */
 
937
 
 
938
    OTV_LIMIT_CHECK( 10 );
 
939
    Coverage           = FT_NEXT_USHORT( p );
 
940
    BacktrackClassDef  = FT_NEXT_USHORT( p );
 
941
    InputClassDef      = FT_NEXT_USHORT( p );
 
942
    LookaheadClassDef  = FT_NEXT_USHORT( p );
 
943
    ChainClassSetCount = FT_NEXT_USHORT( p );
 
944
 
 
945
    OTV_TRACE(( " (ChainClassSetCount = %d)\n", ChainClassSetCount ));
 
946
 
 
947
    otv_Coverage_validate( table + Coverage, valid, -1 );
 
948
 
 
949
    otv_ClassDef_validate( table + BacktrackClassDef,  valid );
 
950
    otv_ClassDef_validate( table + InputClassDef, valid );
 
951
    otv_ClassDef_validate( table + LookaheadClassDef, valid );
 
952
 
 
953
    OTV_LIMIT_CHECK( ChainClassSetCount * 2 );
 
954
 
 
955
    valid->nesting_level++;
 
956
    func          = valid->func[valid->nesting_level];
 
957
    valid->extra1 = valid->lookup_count;
 
958
 
 
959
    for ( ; ChainClassSetCount > 0; ChainClassSetCount-- )
 
960
    {
 
961
      FT_UInt  offset = FT_NEXT_USHORT( p );
 
962
 
 
963
 
 
964
      if ( offset )
 
965
        func( table + offset, valid );
 
966
    }
 
967
 
 
968
    valid->nesting_level--;
 
969
 
 
970
    OTV_EXIT;
 
971
  }
 
972
 
 
973
 
 
974
  /* uses valid->lookup_count */
 
975
 
 
976
  FT_LOCAL_DEF( void )
 
977
  otv_u_x_Ox_y_Oy_z_Oz_p_sp( FT_Bytes       table,
 
978
                             OTV_Validator  valid )
 
979
  {
 
980
    FT_Bytes  p = table;
 
981
    FT_UInt   BacktrackGlyphCount, InputGlyphCount, LookaheadGlyphCount;
 
982
    FT_UInt   count1, count2;
 
983
 
 
984
 
 
985
    OTV_ENTER;
 
986
 
 
987
    p += 2;     /* skip Format */
 
988
 
 
989
    OTV_LIMIT_CHECK( 2 );
 
990
    BacktrackGlyphCount = FT_NEXT_USHORT( p );
 
991
 
 
992
    OTV_TRACE(( " (BacktrackGlyphCount = %d)\n", BacktrackGlyphCount ));
 
993
 
 
994
    OTV_LIMIT_CHECK( BacktrackGlyphCount * 2 + 2 );
 
995
 
 
996
    for ( ; BacktrackGlyphCount > 0; BacktrackGlyphCount-- )
 
997
      otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 );
 
998
 
 
999
    InputGlyphCount = FT_NEXT_USHORT( p );
 
1000
 
 
1001
    OTV_TRACE(( " (InputGlyphCount = %d)\n", InputGlyphCount ));
 
1002
 
 
1003
    OTV_LIMIT_CHECK( InputGlyphCount * 2 + 2 );
 
1004
 
 
1005
    for ( count1 = InputGlyphCount; count1 > 0; count1-- )
 
1006
      otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 );
 
1007
 
 
1008
    LookaheadGlyphCount = FT_NEXT_USHORT( p );
 
1009
 
 
1010
    OTV_TRACE(( " (LookaheadGlyphCount = %d)\n", LookaheadGlyphCount ));
 
1011
 
 
1012
    OTV_LIMIT_CHECK( LookaheadGlyphCount * 2 + 2 );
 
1013
 
 
1014
    for ( ; LookaheadGlyphCount > 0; LookaheadGlyphCount-- )
 
1015
      otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 );
 
1016
 
 
1017
    count2 = FT_NEXT_USHORT( p );
 
1018
 
 
1019
    OTV_TRACE(( " (Count = %d)\n", count2 ));
 
1020
 
 
1021
    OTV_LIMIT_CHECK( count2 * 4 );
 
1022
 
 
1023
    for ( ; count2 > 0; count2-- )
 
1024
    {
 
1025
      if ( FT_NEXT_USHORT( p ) >= InputGlyphCount )
 
1026
        FT_INVALID_DATA;
 
1027
 
 
1028
      if ( FT_NEXT_USHORT( p ) >= valid->lookup_count )
 
1029
        FT_INVALID_DATA;
 
1030
    }
 
1031
 
 
1032
    OTV_EXIT;
 
1033
  }
 
1034
 
 
1035
 
 
1036
  FT_LOCAL_DEF( FT_UInt )
 
1037
  otv_GSUBGPOS_get_Lookup_count( FT_Bytes  table )
 
1038
  {
 
1039
    FT_Bytes  p = table + 8;
 
1040
 
 
1041
 
 
1042
    return otv_LookupList_get_count( table + FT_NEXT_USHORT( p ) );
 
1043
  }
 
1044
 
 
1045
 
 
1046
  FT_LOCAL_DEF( FT_UInt )
 
1047
  otv_GSUBGPOS_have_MarkAttachmentType_flag( FT_Bytes  table )
 
1048
  {
 
1049
    FT_Bytes  p, lookup;
 
1050
    FT_UInt   count;
 
1051
 
 
1052
 
 
1053
    if ( !table )
 
1054
      return 0;
 
1055
 
 
1056
    /* LookupList */
 
1057
    p      = table + 8;
 
1058
    table += FT_NEXT_USHORT( p );
 
1059
 
 
1060
    /* LookupCount */
 
1061
    p     = table;
 
1062
    count = FT_NEXT_USHORT( p );
 
1063
 
 
1064
    for ( ; count > 0; count-- )
 
1065
    {
 
1066
      FT_Bytes  oldp;
 
1067
 
 
1068
 
 
1069
      /* Lookup */
 
1070
      lookup = table + FT_NEXT_USHORT( p );
 
1071
 
 
1072
      oldp = p;
 
1073
 
 
1074
      /* LookupFlag */
 
1075
      p = lookup + 2;
 
1076
      if ( FT_NEXT_USHORT( p ) & 0xFF00U )
 
1077
        return 1;
 
1078
 
 
1079
      p = oldp;
 
1080
    }
 
1081
 
 
1082
    return 0;
 
1083
  }
 
1084
 
 
1085
 
 
1086
/* END */