source: trunk/poppler/freetype2/src/otvalid/otvcommn.c @ 251

Last change on this file since 251 was 251, checked in by Eugene Romanenko, 13 years ago

PDF plugin: freetype library updated to version 2.3.5

File size: 28.4 KB
Line 
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 */
Note: See TracBrowser for help on using the repository browser.