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

Last change on this file since 209 was 209, checked in by Eugene Romanenko, 14 years ago

PDF plugin: freetype library updated to version 2.3.5

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