~ubuntu-branches/ubuntu/utopic/hedgewars/utopic

« back to all changes in this revision

Viewing changes to misc/libfreetype/src/otvalid/otvcommn.c

  • Committer: Package Import Robot
  • Author(s): Gianfranco Costamagna
  • Date: 2014-01-02 12:37:23 UTC
  • mfrom: (19.1.5 sid)
  • Revision ID: package-import@ubuntu.com-20140102123723-6pdhmyj8tb5y8xbg
Tags: 0.9.20.3-1
New upstream minor release, suitable for unstable

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 */