Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4349 | Serge | 1 | /***************************************************************************/ |
2 | /* */ |
||
3 | /* gxvmorx.c */ |
||
4 | /* */ |
||
5 | /* TrueTypeGX/AAT morx table validation (body). */ |
||
6 | /* */ |
||
7 | /* Copyright 2005, 2008, 2013 by */ |
||
8 | /* suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ |
||
9 | /* David Turner, Robert Wilhelm, and Werner Lemberg. */ |
||
10 | /* */ |
||
11 | /* This file is part of the FreeType project, and may only be used, */ |
||
12 | /* modified, and distributed under the terms of the FreeType project */ |
||
13 | /* license, LICENSE.TXT. By continuing to use, modify, or distribute */ |
||
14 | /* this file you indicate that you have read the license and */ |
||
15 | /* understand and accept it fully. */ |
||
16 | /* */ |
||
17 | /***************************************************************************/ |
||
18 | |||
19 | /***************************************************************************/ |
||
20 | /* */ |
||
21 | /* gxvalid is derived from both gxlayout module and otvalid module. */ |
||
22 | /* Development of gxlayout is supported by the Information-technology */ |
||
23 | /* Promotion Agency(IPA), Japan. */ |
||
24 | /* */ |
||
25 | /***************************************************************************/ |
||
26 | |||
27 | |||
28 | #include "gxvmorx.h" |
||
29 | |||
30 | |||
31 | /*************************************************************************/ |
||
32 | /* */ |
||
33 | /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ |
||
34 | /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ |
||
35 | /* messages during execution. */ |
||
36 | /* */ |
||
37 | #undef FT_COMPONENT |
||
38 | #define FT_COMPONENT trace_gxvmorx |
||
39 | |||
40 | |||
41 | static void |
||
42 | gxv_morx_subtables_validate( FT_Bytes table, |
||
43 | FT_Bytes limit, |
||
44 | FT_UShort nSubtables, |
||
45 | GXV_Validator valid ) |
||
46 | { |
||
47 | FT_Bytes p = table; |
||
48 | |||
49 | GXV_Validate_Func fmt_funcs_table[] = |
||
50 | { |
||
51 | gxv_morx_subtable_type0_validate, /* 0 */ |
||
52 | gxv_morx_subtable_type1_validate, /* 1 */ |
||
53 | gxv_morx_subtable_type2_validate, /* 2 */ |
||
54 | NULL, /* 3 */ |
||
55 | gxv_morx_subtable_type4_validate, /* 4 */ |
||
56 | gxv_morx_subtable_type5_validate, /* 5 */ |
||
57 | |||
58 | }; |
||
59 | |||
60 | FT_UShort i; |
||
61 | |||
62 | |||
63 | GXV_NAME_ENTER( "subtables in a chain" ); |
||
64 | |||
65 | for ( i = 0; i < nSubtables; i++ ) |
||
66 | { |
||
67 | GXV_Validate_Func func; |
||
68 | |||
69 | FT_ULong length; |
||
70 | FT_ULong coverage; |
||
71 | #ifdef GXV_LOAD_UNUSED_VARS |
||
72 | FT_ULong subFeatureFlags; |
||
73 | #endif |
||
74 | FT_ULong type; |
||
75 | FT_ULong rest; |
||
76 | |||
77 | |||
78 | GXV_LIMIT_CHECK( 4 + 4 + 4 ); |
||
79 | length = FT_NEXT_ULONG( p ); |
||
80 | coverage = FT_NEXT_ULONG( p ); |
||
81 | #ifdef GXV_LOAD_UNUSED_VARS |
||
82 | subFeatureFlags = FT_NEXT_ULONG( p ); |
||
83 | #else |
||
84 | p += 4; |
||
85 | #endif |
||
86 | |||
87 | GXV_TRACE(( "validating chain subtable %d/%d (%d bytes)\n", |
||
88 | i + 1, nSubtables, length )); |
||
89 | |||
90 | type = coverage & 0x0007; |
||
91 | rest = length - ( 4 + 4 + 4 ); |
||
92 | GXV_LIMIT_CHECK( rest ); |
||
93 | |||
94 | /* morx coverage consists of mort_coverage & 16bit padding */ |
||
95 | gxv_mort_coverage_validate( (FT_UShort)( ( coverage >> 16 ) | coverage ), |
||
96 | valid ); |
||
97 | if ( type > 5 ) |
||
98 | FT_INVALID_FORMAT; |
||
99 | |||
100 | func = fmt_funcs_table[type]; |
||
101 | if ( func == NULL ) |
||
102 | GXV_TRACE(( "morx type %d is reserved\n", type )); |
||
103 | |||
104 | func( p, p + rest, valid ); |
||
105 | |||
106 | /* TODO: subFeatureFlags should be unique in a table? */ |
||
107 | p += rest; |
||
108 | } |
||
109 | |||
110 | valid->subtable_length = p - table; |
||
111 | |||
112 | GXV_EXIT; |
||
113 | } |
||
114 | |||
115 | |||
116 | static void |
||
117 | gxv_morx_chain_validate( FT_Bytes table, |
||
118 | FT_Bytes limit, |
||
119 | GXV_Validator valid ) |
||
120 | { |
||
121 | FT_Bytes p = table; |
||
122 | #ifdef GXV_LOAD_UNUSED_VARS |
||
123 | FT_ULong defaultFlags; |
||
124 | #endif |
||
125 | FT_ULong chainLength; |
||
126 | FT_ULong nFeatureFlags; |
||
127 | FT_ULong nSubtables; |
||
128 | |||
129 | |||
130 | GXV_NAME_ENTER( "morx chain header" ); |
||
131 | |||
132 | GXV_LIMIT_CHECK( 4 + 4 + 4 + 4 ); |
||
133 | #ifdef GXV_LOAD_UNUSED_VARS |
||
134 | defaultFlags = FT_NEXT_ULONG( p ); |
||
135 | #else |
||
136 | p += 4; |
||
137 | #endif |
||
138 | chainLength = FT_NEXT_ULONG( p ); |
||
139 | nFeatureFlags = FT_NEXT_ULONG( p ); |
||
140 | nSubtables = FT_NEXT_ULONG( p ); |
||
141 | |||
142 | /* feature-array of morx is same with that of mort */ |
||
143 | gxv_mort_featurearray_validate( p, limit, nFeatureFlags, valid ); |
||
144 | p += valid->subtable_length; |
||
145 | |||
146 | if ( nSubtables >= 0x10000L ) |
||
147 | FT_INVALID_DATA; |
||
148 | |||
149 | gxv_morx_subtables_validate( p, table + chainLength, |
||
150 | (FT_UShort)nSubtables, valid ); |
||
151 | |||
152 | valid->subtable_length = chainLength; |
||
153 | |||
154 | /* TODO: defaultFlags should be compared with the flags in tables */ |
||
155 | |||
156 | GXV_EXIT; |
||
157 | } |
||
158 | |||
159 | |||
160 | FT_LOCAL_DEF( void ) |
||
161 | gxv_morx_validate( FT_Bytes table, |
||
162 | FT_Face face, |
||
163 | FT_Validator ftvalid ) |
||
164 | { |
||
165 | GXV_ValidatorRec validrec; |
||
166 | GXV_Validator valid = &validrec; |
||
167 | FT_Bytes p = table; |
||
168 | FT_Bytes limit = 0; |
||
169 | FT_ULong version; |
||
170 | FT_ULong nChains; |
||
171 | FT_ULong i; |
||
172 | |||
173 | |||
174 | valid->root = ftvalid; |
||
175 | valid->face = face; |
||
176 | |||
177 | FT_TRACE3(( "validating `morx' table\n" )); |
||
178 | GXV_INIT; |
||
179 | |||
180 | GXV_LIMIT_CHECK( 4 + 4 ); |
||
181 | version = FT_NEXT_ULONG( p ); |
||
182 | nChains = FT_NEXT_ULONG( p ); |
||
183 | |||
184 | if ( version != 0x00020000UL ) |
||
185 | FT_INVALID_FORMAT; |
||
186 | |||
187 | for ( i = 0; i < nChains; i++ ) |
||
188 | { |
||
189 | GXV_TRACE(( "validating chain %d/%d\n", i + 1, nChains )); |
||
190 | GXV_32BIT_ALIGNMENT_VALIDATE( p - table ); |
||
191 | gxv_morx_chain_validate( p, limit, valid ); |
||
192 | p += valid->subtable_length; |
||
193 | } |
||
194 | |||
195 | FT_TRACE4(( "\n" )); |
||
196 | } |
||
197 | |||
198 | |||
199 | /* END */>> |