Delete all Trailing spaces in code.
[reactos.git] / reactos / dll / 3rdparty / freetype / src / otvalid / otvcommn.c
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 */