1 /***************************************************************************/
5 /* OpenType common tables validation (body). */
7 /* Copyright 2004, 2005, 2006, 2007 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
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. */
16 /***************************************************************************/
22 /*************************************************************************/
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. */
29 #define FT_COMPONENT trace_otvcommon
32 /*************************************************************************/
33 /*************************************************************************/
35 /***** COVERAGE TABLE *****/
37 /*************************************************************************/
38 /*************************************************************************/
41 otv_Coverage_validate( FT_Bytes table,
43 FT_Int expected_count )
46 FT_UInt CoverageFormat;
50 OTV_NAME_ENTER( "Coverage" );
53 CoverageFormat = FT_NEXT_USHORT( p );
55 OTV_TRACE(( " (format %d)\n", CoverageFormat ));
57 switch ( CoverageFormat )
59 case 1: /* CoverageFormat1 */
65 GlyphCount = FT_NEXT_USHORT( p );
67 OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount ));
69 OTV_LIMIT_CHECK( GlyphCount * 2 ); /* GlyphArray */
71 for ( i = 0; i < GlyphCount; ++i )
76 gid = FT_NEXT_USHORT( p );
77 if ( gid >= valid->glyph_count )
85 case 2: /* CoverageFormat2 */
87 FT_UInt n, RangeCount;
88 FT_UInt Start, End, StartCoverageIndex, last = 0;
91 RangeCount = FT_NEXT_USHORT( p );
93 OTV_TRACE(( " (RangeCount = %d)\n", RangeCount ));
95 OTV_LIMIT_CHECK( RangeCount * 6 );
98 for ( n = 0; n < RangeCount; n++ )
100 Start = FT_NEXT_USHORT( p );
101 End = FT_NEXT_USHORT( p );
102 StartCoverageIndex = FT_NEXT_USHORT( p );
104 if ( Start > End || StartCoverageIndex != total )
107 if ( End >= valid->glyph_count )
110 if ( n > 0 && Start <= last )
113 total += End - Start + 1;
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 )
133 FT_LOCAL_DEF( FT_UInt )
134 otv_Coverage_get_first( FT_Bytes table )
139 p += 4; /* skip CoverageFormat and Glyph/RangeCount */
141 return FT_NEXT_USHORT( p );
145 FT_LOCAL_DEF( FT_UInt )
146 otv_Coverage_get_last( FT_Bytes table )
149 FT_UInt CoverageFormat = FT_NEXT_USHORT( p );
150 FT_UInt count = FT_NEXT_USHORT( p ); /* Glyph/RangeCount */
154 switch ( CoverageFormat )
157 p += ( count - 1 ) * 2;
158 result = FT_NEXT_USHORT( p );
162 p += ( count - 1 ) * 6 + 2;
163 result = FT_NEXT_USHORT( p );
174 FT_LOCAL_DEF( FT_UInt )
175 otv_Coverage_get_count( FT_Bytes table )
178 FT_UInt CoverageFormat = FT_NEXT_USHORT( p );
179 FT_UInt count = FT_NEXT_USHORT( p ); /* Glyph/RangeCount */
183 switch ( CoverageFormat )
193 for ( ; count > 0; count-- )
195 Start = FT_NEXT_USHORT( p );
196 End = FT_NEXT_USHORT( p );
197 p += 2; /* skip StartCoverageIndex */
199 result += End - Start + 1;
212 /*************************************************************************/
213 /*************************************************************************/
215 /***** CLASS DEFINITION TABLE *****/
217 /*************************************************************************/
218 /*************************************************************************/
221 otv_ClassDef_validate( FT_Bytes table,
222 OTV_Validator valid )
228 OTV_NAME_ENTER( "ClassDef" );
230 OTV_LIMIT_CHECK( 4 );
231 ClassFormat = FT_NEXT_USHORT( p );
233 OTV_TRACE(( " (format %d)\n", ClassFormat ));
235 switch ( ClassFormat )
237 case 1: /* ClassDefFormat1 */
243 OTV_LIMIT_CHECK( 4 );
245 StartGlyph = FT_NEXT_USHORT( p );
246 GlyphCount = FT_NEXT_USHORT( p );
248 OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount ));
250 OTV_LIMIT_CHECK( GlyphCount * 2 ); /* ClassValueArray */
252 if ( StartGlyph + GlyphCount - 1 >= valid->glyph_count )
257 case 2: /* ClassDefFormat2 */
259 FT_UInt n, ClassRangeCount;
260 FT_UInt Start, End, last = 0;
263 ClassRangeCount = FT_NEXT_USHORT( p );
265 OTV_TRACE(( " (ClassRangeCount = %d)\n", ClassRangeCount ));
267 OTV_LIMIT_CHECK( ClassRangeCount * 6 );
269 /* ClassRangeRecord */
270 for ( n = 0; n < ClassRangeCount; n++ )
272 Start = FT_NEXT_USHORT( p );
273 End = FT_NEXT_USHORT( p );
274 p += 2; /* skip Class */
276 if ( Start > End || ( n > 0 && Start <= last ) )
279 if ( End >= valid->glyph_count )
291 /* no need to check glyph indices used as input to class definition */
292 /* tables since even invalid glyph indices return a meaningful result */
298 /*************************************************************************/
299 /*************************************************************************/
301 /***** DEVICE TABLE *****/
303 /*************************************************************************/
304 /*************************************************************************/
307 otv_Device_validate( FT_Bytes table,
308 OTV_Validator valid )
311 FT_UInt StartSize, EndSize, DeltaFormat, count;
314 OTV_NAME_ENTER( "Device" );
316 OTV_LIMIT_CHECK( 8 );
317 StartSize = FT_NEXT_USHORT( p );
318 EndSize = FT_NEXT_USHORT( p );
319 DeltaFormat = FT_NEXT_USHORT( p );
321 if ( DeltaFormat < 1 || DeltaFormat > 3 )
324 if ( EndSize < StartSize )
327 count = EndSize - StartSize + 1;
328 OTV_LIMIT_CHECK( ( 1 << DeltaFormat ) * count / 8 ); /* DeltaValue */
334 /*************************************************************************/
335 /*************************************************************************/
337 /***** LOOKUPS *****/
339 /*************************************************************************/
340 /*************************************************************************/
342 /* uses valid->type_count */
343 /* uses valid->type_funcs */
346 otv_Lookup_validate( FT_Bytes table,
347 OTV_Validator valid )
350 FT_UInt LookupType, SubTableCount;
351 OTV_Validate_Func validate;
354 OTV_NAME_ENTER( "Lookup" );
356 OTV_LIMIT_CHECK( 6 );
357 LookupType = FT_NEXT_USHORT( p );
358 p += 2; /* skip LookupFlag */
359 SubTableCount = FT_NEXT_USHORT( p );
361 OTV_TRACE(( " (type %d)\n", LookupType ));
363 if ( LookupType == 0 || LookupType > valid->type_count )
366 validate = valid->type_funcs[LookupType - 1];
368 OTV_TRACE(( " (SubTableCount = %d)\n", SubTableCount ));
370 OTV_LIMIT_CHECK( SubTableCount * 2 );
373 for ( ; SubTableCount > 0; SubTableCount-- )
374 validate( table + FT_NEXT_USHORT( p ), valid );
380 /* uses valid->lookup_count */
383 otv_LookupList_validate( FT_Bytes table,
384 OTV_Validator valid )
390 OTV_NAME_ENTER( "LookupList" );
392 OTV_LIMIT_CHECK( 2 );
393 LookupCount = FT_NEXT_USHORT( p );
395 OTV_TRACE(( " (LookupCount = %d)\n", LookupCount ));
397 OTV_LIMIT_CHECK( LookupCount * 2 );
399 valid->lookup_count = LookupCount;
402 for ( ; LookupCount > 0; LookupCount-- )
403 otv_Lookup_validate( table + FT_NEXT_USHORT( p ), valid );
410 otv_LookupList_get_count( FT_Bytes table )
412 return FT_NEXT_USHORT( table );
416 /*************************************************************************/
417 /*************************************************************************/
419 /***** FEATURES *****/
421 /*************************************************************************/
422 /*************************************************************************/
424 /* uses valid->lookup_count */
427 otv_Feature_validate( FT_Bytes table,
428 OTV_Validator valid )
434 OTV_NAME_ENTER( "Feature" );
436 OTV_LIMIT_CHECK( 4 );
437 p += 2; /* skip FeatureParams (unused) */
438 LookupCount = FT_NEXT_USHORT( p );
440 OTV_TRACE(( " (LookupCount = %d)\n", LookupCount ));
442 OTV_LIMIT_CHECK( LookupCount * 2 );
444 /* LookupListIndex */
445 for ( ; LookupCount > 0; LookupCount-- )
446 if ( FT_NEXT_USHORT( p ) >= valid->lookup_count )
454 otv_Feature_get_count( FT_Bytes table )
456 return FT_NEXT_USHORT( table );
460 /* sets valid->lookup_count */
463 otv_FeatureList_validate( FT_Bytes table,
465 OTV_Validator valid )
468 FT_UInt FeatureCount;
471 OTV_NAME_ENTER( "FeatureList" );
473 OTV_LIMIT_CHECK( 2 );
474 FeatureCount = FT_NEXT_USHORT( p );
476 OTV_TRACE(( " (FeatureCount = %d)\n", FeatureCount ));
478 OTV_LIMIT_CHECK( FeatureCount * 2 );
480 valid->lookup_count = otv_LookupList_get_count( lookups );
483 for ( ; FeatureCount > 0; FeatureCount-- )
485 p += 4; /* skip FeatureTag */
488 otv_Feature_validate( table + FT_NEXT_USHORT( p ), valid );
495 /*************************************************************************/
496 /*************************************************************************/
498 /***** LANGUAGE SYSTEM *****/
500 /*************************************************************************/
501 /*************************************************************************/
504 /* uses valid->extra1 (number of features) */
507 otv_LangSys_validate( FT_Bytes table,
508 OTV_Validator valid )
511 FT_UInt ReqFeatureIndex;
512 FT_UInt FeatureCount;
515 OTV_NAME_ENTER( "LangSys" );
517 OTV_LIMIT_CHECK( 6 );
518 p += 2; /* skip LookupOrder (unused) */
519 ReqFeatureIndex = FT_NEXT_USHORT( p );
520 FeatureCount = FT_NEXT_USHORT( p );
522 OTV_TRACE(( " (ReqFeatureIndex = %d)\n", ReqFeatureIndex ));
523 OTV_TRACE(( " (FeatureCount = %d)\n", FeatureCount ));
525 if ( ReqFeatureIndex != 0xFFFFU && ReqFeatureIndex >= valid->extra1 )
528 OTV_LIMIT_CHECK( FeatureCount * 2 );
531 for ( ; FeatureCount > 0; FeatureCount-- )
532 if ( FT_NEXT_USHORT( p ) >= valid->extra1 )
539 /*************************************************************************/
540 /*************************************************************************/
542 /***** SCRIPTS *****/
544 /*************************************************************************/
545 /*************************************************************************/
548 otv_Script_validate( FT_Bytes table,
549 OTV_Validator valid )
551 FT_UInt DefaultLangSys, LangSysCount;
555 OTV_NAME_ENTER( "Script" );
557 OTV_LIMIT_CHECK( 4 );
558 DefaultLangSys = FT_NEXT_USHORT( p );
559 LangSysCount = FT_NEXT_USHORT( p );
561 OTV_TRACE(( " (LangSysCount = %d)\n", LangSysCount ));
563 if ( DefaultLangSys != 0 )
564 otv_LangSys_validate( table + DefaultLangSys, valid );
566 OTV_LIMIT_CHECK( LangSysCount * 6 );
569 for ( ; LangSysCount > 0; LangSysCount-- )
571 p += 4; /* skip LangSysTag */
574 otv_LangSys_validate( table + FT_NEXT_USHORT( p ), valid );
581 /* sets valid->extra1 (number of features) */
584 otv_ScriptList_validate( FT_Bytes table,
586 OTV_Validator valid )
592 OTV_NAME_ENTER( "ScriptList" );
594 OTV_LIMIT_CHECK( 2 );
595 ScriptCount = FT_NEXT_USHORT( p );
597 OTV_TRACE(( " (ScriptCount = %d)\n", ScriptCount ));
599 OTV_LIMIT_CHECK( ScriptCount * 6 );
601 valid->extra1 = otv_Feature_get_count( features );
604 for ( ; ScriptCount > 0; ScriptCount-- )
606 p += 4; /* skip ScriptTag */
608 otv_Script_validate( table + FT_NEXT_USHORT( p ), valid ); /* Script */
615 /*************************************************************************/
616 /*************************************************************************/
618 /***** UTILITY FUNCTIONS *****/
620 /*************************************************************************/
621 /*************************************************************************/
629 sxy: struct [x], using external y count
638 Onx: Offset (NULL) [x]
642 otv_x_Ox( FT_Bytes table,
643 OTV_Validator valid )
647 OTV_Validate_Func func;
652 OTV_LIMIT_CHECK( 2 );
653 Count = FT_NEXT_USHORT( p );
655 OTV_TRACE(( " (Count = %d)\n", Count ));
657 OTV_LIMIT_CHECK( Count * 2 );
659 valid->nesting_level++;
660 func = valid->func[valid->nesting_level];
662 for ( ; Count > 0; Count-- )
663 func( table + FT_NEXT_USHORT( p ), valid );
665 valid->nesting_level--;
672 otv_u_C_x_Ox( FT_Bytes table,
673 OTV_Validator valid )
676 FT_UInt Count, Coverage;
677 OTV_Validate_Func func;
682 p += 2; /* skip Format */
684 OTV_LIMIT_CHECK( 4 );
685 Coverage = FT_NEXT_USHORT( p );
686 Count = FT_NEXT_USHORT( p );
688 OTV_TRACE(( " (Count = %d)\n", Count ));
690 otv_Coverage_validate( table + Coverage, valid, Count );
692 OTV_LIMIT_CHECK( Count * 2 );
694 valid->nesting_level++;
695 func = valid->func[valid->nesting_level];
697 for ( ; Count > 0; Count-- )
698 func( table + FT_NEXT_USHORT( p ), valid );
700 valid->nesting_level--;
706 /* uses valid->extra1 (if > 0: array value limit) */
709 otv_x_ux( FT_Bytes table,
710 OTV_Validator valid )
718 OTV_LIMIT_CHECK( 2 );
719 Count = FT_NEXT_USHORT( p );
721 OTV_TRACE(( " (Count = %d)\n", Count ));
723 OTV_LIMIT_CHECK( Count * 2 );
727 for ( ; Count > 0; Count-- )
728 if ( FT_NEXT_USHORT( p ) >= valid->extra1 )
736 /* `ux' in the function's name is not really correct since only x-1 */
737 /* elements are tested */
739 /* uses valid->extra1 (array value limit) */
742 otv_x_y_ux_sy( FT_Bytes table,
743 OTV_Validator valid )
746 FT_UInt Count1, Count2;
751 OTV_LIMIT_CHECK( 4 );
752 Count1 = FT_NEXT_USHORT( p );
753 Count2 = FT_NEXT_USHORT( p );
755 OTV_TRACE(( " (Count1 = %d)\n", Count1 ));
756 OTV_TRACE(( " (Count2 = %d)\n", Count2 ));
761 OTV_LIMIT_CHECK( ( Count1 - 1 ) * 2 + Count2 * 4 );
762 p += ( Count1 - 1 ) * 2;
764 for ( ; Count2 > 0; Count2-- )
766 if ( FT_NEXT_USHORT( p ) >= Count1 )
769 if ( FT_NEXT_USHORT( p ) >= valid->extra1 )
777 /* `uy' in the function's name is not really correct since only y-1 */
778 /* elements are tested */
780 /* uses valid->extra1 (array value limit) */
783 otv_x_ux_y_uy_z_uz_p_sp( FT_Bytes table,
784 OTV_Validator valid )
787 FT_UInt BacktrackCount, InputCount, LookaheadCount;
793 OTV_LIMIT_CHECK( 2 );
794 BacktrackCount = FT_NEXT_USHORT( p );
796 OTV_TRACE(( " (BacktrackCount = %d)\n", BacktrackCount ));
798 OTV_LIMIT_CHECK( BacktrackCount * 2 + 2 );
799 p += BacktrackCount * 2;
801 InputCount = FT_NEXT_USHORT( p );
802 if ( InputCount == 0 )
805 OTV_TRACE(( " (InputCount = %d)\n", InputCount ));
807 OTV_LIMIT_CHECK( InputCount * 2 );
808 p += ( InputCount - 1 ) * 2;
810 LookaheadCount = FT_NEXT_USHORT( p );
812 OTV_TRACE(( " (LookaheadCount = %d)\n", LookaheadCount ));
814 OTV_LIMIT_CHECK( LookaheadCount * 2 + 2 );
815 p += LookaheadCount * 2;
817 Count = FT_NEXT_USHORT( p );
819 OTV_TRACE(( " (Count = %d)\n", Count ));
821 OTV_LIMIT_CHECK( Count * 4 );
823 for ( ; Count > 0; Count-- )
825 if ( FT_NEXT_USHORT( p ) >= InputCount )
828 if ( FT_NEXT_USHORT( p ) >= valid->extra1 )
836 /* sets valid->extra1 (valid->lookup_count) */
839 otv_u_O_O_x_Onx( FT_Bytes table,
840 OTV_Validator valid )
843 FT_UInt Coverage, ClassDef, ClassSetCount;
844 OTV_Validate_Func func;
849 p += 2; /* skip Format */
851 OTV_LIMIT_CHECK( 6 );
852 Coverage = FT_NEXT_USHORT( p );
853 ClassDef = FT_NEXT_USHORT( p );
854 ClassSetCount = FT_NEXT_USHORT( p );
856 OTV_TRACE(( " (ClassSetCount = %d)\n", ClassSetCount ));
858 otv_Coverage_validate( table + Coverage, valid, -1 );
859 otv_ClassDef_validate( table + ClassDef, valid );
861 OTV_LIMIT_CHECK( ClassSetCount * 2 );
863 valid->nesting_level++;
864 func = valid->func[valid->nesting_level];
865 valid->extra1 = valid->lookup_count;
867 for ( ; ClassSetCount > 0; ClassSetCount-- )
869 FT_UInt offset = FT_NEXT_USHORT( p );
873 func( table + offset, valid );
876 valid->nesting_level--;
882 /* uses valid->lookup_count */
885 otv_u_x_y_Ox_sy( FT_Bytes table,
886 OTV_Validator valid )
889 FT_UInt GlyphCount, Count, count1;
894 p += 2; /* skip Format */
896 OTV_LIMIT_CHECK( 4 );
897 GlyphCount = FT_NEXT_USHORT( p );
898 Count = FT_NEXT_USHORT( p );
900 OTV_TRACE(( " (GlyphCount = %d)\n", GlyphCount ));
901 OTV_TRACE(( " (Count = %d)\n", Count ));
903 OTV_LIMIT_CHECK( GlyphCount * 2 + Count * 4 );
905 for ( count1 = GlyphCount; count1 > 0; count1-- )
906 otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 );
908 for ( ; Count > 0; Count-- )
910 if ( FT_NEXT_USHORT( p ) >= GlyphCount )
913 if ( FT_NEXT_USHORT( p ) >= valid->lookup_count )
921 /* sets valid->extra1 (valid->lookup_count) */
924 otv_u_O_O_O_O_x_Onx( FT_Bytes table,
925 OTV_Validator valid )
929 FT_UInt BacktrackClassDef, InputClassDef, LookaheadClassDef;
930 FT_UInt ChainClassSetCount;
931 OTV_Validate_Func func;
936 p += 2; /* skip Format */
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 );
945 OTV_TRACE(( " (ChainClassSetCount = %d)\n", ChainClassSetCount ));
947 otv_Coverage_validate( table + Coverage, valid, -1 );
949 otv_ClassDef_validate( table + BacktrackClassDef, valid );
950 otv_ClassDef_validate( table + InputClassDef, valid );
951 otv_ClassDef_validate( table + LookaheadClassDef, valid );
953 OTV_LIMIT_CHECK( ChainClassSetCount * 2 );
955 valid->nesting_level++;
956 func = valid->func[valid->nesting_level];
957 valid->extra1 = valid->lookup_count;
959 for ( ; ChainClassSetCount > 0; ChainClassSetCount-- )
961 FT_UInt offset = FT_NEXT_USHORT( p );
965 func( table + offset, valid );
968 valid->nesting_level--;
974 /* uses valid->lookup_count */
977 otv_u_x_Ox_y_Oy_z_Oz_p_sp( FT_Bytes table,
978 OTV_Validator valid )
981 FT_UInt BacktrackGlyphCount, InputGlyphCount, LookaheadGlyphCount;
982 FT_UInt count1, count2;
987 p += 2; /* skip Format */
989 OTV_LIMIT_CHECK( 2 );
990 BacktrackGlyphCount = FT_NEXT_USHORT( p );
992 OTV_TRACE(( " (BacktrackGlyphCount = %d)\n", BacktrackGlyphCount ));
994 OTV_LIMIT_CHECK( BacktrackGlyphCount * 2 + 2 );
996 for ( ; BacktrackGlyphCount > 0; BacktrackGlyphCount-- )
997 otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 );
999 InputGlyphCount = FT_NEXT_USHORT( p );
1001 OTV_TRACE(( " (InputGlyphCount = %d)\n", InputGlyphCount ));
1003 OTV_LIMIT_CHECK( InputGlyphCount * 2 + 2 );
1005 for ( count1 = InputGlyphCount; count1 > 0; count1-- )
1006 otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 );
1008 LookaheadGlyphCount = FT_NEXT_USHORT( p );
1010 OTV_TRACE(( " (LookaheadGlyphCount = %d)\n", LookaheadGlyphCount ));
1012 OTV_LIMIT_CHECK( LookaheadGlyphCount * 2 + 2 );
1014 for ( ; LookaheadGlyphCount > 0; LookaheadGlyphCount-- )
1015 otv_Coverage_validate( table + FT_NEXT_USHORT( p ), valid, -1 );
1017 count2 = FT_NEXT_USHORT( p );
1019 OTV_TRACE(( " (Count = %d)\n", count2 ));
1021 OTV_LIMIT_CHECK( count2 * 4 );
1023 for ( ; count2 > 0; count2-- )
1025 if ( FT_NEXT_USHORT( p ) >= InputGlyphCount )
1028 if ( FT_NEXT_USHORT( p ) >= valid->lookup_count )
1036 FT_LOCAL_DEF( FT_UInt )
1037 otv_GSUBGPOS_get_Lookup_count( FT_Bytes table )
1039 FT_Bytes p = table + 8;
1042 return otv_LookupList_get_count( table + FT_NEXT_USHORT( p ) );
1046 FT_LOCAL_DEF( FT_UInt )
1047 otv_GSUBGPOS_have_MarkAttachmentType_flag( FT_Bytes table )
1058 table += FT_NEXT_USHORT( p );
1062 count = FT_NEXT_USHORT( p );
1064 for ( ; count > 0; count-- )
1070 lookup = table + FT_NEXT_USHORT( p );
1076 if ( FT_NEXT_USHORT( p ) & 0xFF00U )