Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
3918 | Serge | 1 | /***************************************************************************/ |
2 | /* */ |
||
3 | /* gxvtrak.c */ |
||
4 | /* */ |
||
5 | /* TrueTypeGX/AAT trak table validation (body). */ |
||
6 | /* */ |
||
7 | /* Copyright 2004, 2005 by suzuki toshiya, Masatake YAMATO, Red Hat K.K., */ |
||
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 | /* */ |
||
20 | /* gxvalid is derived from both gxlayout module and otvalid module. */ |
||
21 | /* Development of gxlayout is supported by the Information-technology */ |
||
22 | /* Promotion Agency(IPA), Japan. */ |
||
23 | /* */ |
||
24 | /***************************************************************************/ |
||
25 | |||
26 | |||
27 | #include "gxvalid.h" |
||
28 | #include "gxvcommn.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_gxvtrak |
||
39 | |||
40 | |||
41 | /*************************************************************************/ |
||
42 | /*************************************************************************/ |
||
43 | /***** *****/ |
||
44 | /***** Data and Types *****/ |
||
45 | /***** *****/ |
||
46 | /*************************************************************************/ |
||
47 | /*************************************************************************/ |
||
48 | |||
49 | /* |
||
50 | * referred track table format specification: |
||
51 | * http://developer.apple.com/fonts/TTRefMan/RM06/Chap6trak.html |
||
52 | * last update was 1996. |
||
53 | * ---------------------------------------------- |
||
54 | * [MINIMUM HEADER]: GXV_TRAK_SIZE_MIN |
||
55 | * version (fixed: 32bit) = 0x00010000 |
||
56 | * format (uint16: 16bit) = 0 is only defined (1996) |
||
57 | * horizOffset (uint16: 16bit) |
||
58 | * vertOffset (uint16: 16bit) |
||
59 | * reserved (uint16: 16bit) = 0 |
||
60 | * ---------------------------------------------- |
||
61 | * [VARIABLE BODY]: |
||
62 | * horizData |
||
63 | * header ( 2 + 2 + 4 |
||
64 | * trackTable + nTracks * ( 4 + 2 + 2 ) |
||
65 | * sizeTable + nSizes * 4 ) |
||
66 | * ---------------------------------------------- |
||
67 | * vertData |
||
68 | * header ( 2 + 2 + 4 |
||
69 | * trackTable + nTracks * ( 4 + 2 + 2 ) |
||
70 | * sizeTable + nSizes * 4 ) |
||
71 | * ---------------------------------------------- |
||
72 | */ |
||
73 | typedef struct GXV_trak_DataRec_ |
||
74 | { |
||
75 | FT_UShort trackValueOffset_min; |
||
76 | FT_UShort trackValueOffset_max; |
||
77 | |||
78 | } GXV_trak_DataRec, *GXV_trak_Data; |
||
79 | |||
80 | |||
81 | #define GXV_TRAK_DATA( FIELD ) GXV_TABLE_DATA( trak, FIELD ) |
||
82 | |||
83 | |||
84 | /*************************************************************************/ |
||
85 | /*************************************************************************/ |
||
86 | /***** *****/ |
||
87 | /***** UTILITY FUNCTIONS *****/ |
||
88 | /***** *****/ |
||
89 | /*************************************************************************/ |
||
90 | /*************************************************************************/ |
||
91 | |||
92 | static void |
||
93 | gxv_trak_trackTable_validate( FT_Bytes table, |
||
94 | FT_Bytes limit, |
||
95 | FT_UShort nTracks, |
||
96 | GXV_Validator valid ) |
||
97 | { |
||
98 | FT_Bytes p = table; |
||
99 | |||
100 | FT_Fixed track, t; |
||
101 | FT_UShort nameIndex; |
||
102 | FT_UShort offset; |
||
103 | FT_UShort i, j; |
||
104 | |||
105 | |||
106 | GXV_NAME_ENTER( "trackTable" ); |
||
107 | |||
108 | GXV_TRAK_DATA( trackValueOffset_min ) = 0xFFFFU; |
||
109 | GXV_TRAK_DATA( trackValueOffset_max ) = 0x0000; |
||
110 | |||
111 | GXV_LIMIT_CHECK( nTracks * ( 4 + 2 + 2 ) ); |
||
112 | |||
113 | for ( i = 0; i < nTracks; i ++ ) |
||
114 | { |
||
115 | p = table + i * ( 4 + 2 + 2 ); |
||
116 | track = FT_NEXT_LONG( p ); |
||
117 | nameIndex = FT_NEXT_USHORT( p ); |
||
118 | offset = FT_NEXT_USHORT( p ); |
||
119 | |||
120 | if ( offset < GXV_TRAK_DATA( trackValueOffset_min ) ) |
||
121 | GXV_TRAK_DATA( trackValueOffset_min ) = offset; |
||
122 | if ( offset > GXV_TRAK_DATA( trackValueOffset_max ) ) |
||
123 | GXV_TRAK_DATA( trackValueOffset_max ) = offset; |
||
124 | |||
125 | gxv_sfntName_validate( nameIndex, 256, 32767, valid ); |
||
126 | |||
127 | for ( j = i; j < nTracks; j ++ ) |
||
128 | { |
||
129 | p = table + j * ( 4 + 2 + 2 ); |
||
130 | t = FT_NEXT_LONG( p ); |
||
131 | if ( t == track ) |
||
132 | GXV_TRACE(( "duplicated entries found for track value 0x%x\n", |
||
133 | track )); |
||
134 | } |
||
135 | } |
||
136 | |||
137 | valid->subtable_length = p - table; |
||
138 | GXV_EXIT; |
||
139 | } |
||
140 | |||
141 | |||
142 | static void |
||
143 | gxv_trak_trackData_validate( FT_Bytes table, |
||
144 | FT_Bytes limit, |
||
145 | GXV_Validator valid ) |
||
146 | { |
||
147 | FT_Bytes p = table; |
||
148 | FT_UShort nTracks; |
||
149 | FT_UShort nSizes; |
||
150 | FT_ULong sizeTableOffset; |
||
151 | |||
152 | GXV_ODTECT( 4, odtect ); |
||
153 | |||
154 | |||
155 | GXV_ODTECT_INIT( odtect ); |
||
156 | GXV_NAME_ENTER( "trackData" ); |
||
157 | |||
158 | /* read the header of trackData */ |
||
159 | GXV_LIMIT_CHECK( 2 + 2 + 4 ); |
||
160 | nTracks = FT_NEXT_USHORT( p ); |
||
161 | nSizes = FT_NEXT_USHORT( p ); |
||
162 | sizeTableOffset = FT_NEXT_ULONG( p ); |
||
163 | |||
164 | gxv_odtect_add_range( table, p - table, "trackData header", odtect ); |
||
165 | |||
166 | /* validate trackTable */ |
||
167 | gxv_trak_trackTable_validate( p, limit, nTracks, valid ); |
||
168 | gxv_odtect_add_range( p, valid->subtable_length, |
||
169 | "trackTable", odtect ); |
||
170 | |||
171 | /* sizeTable is array of FT_Fixed, don't check contents */ |
||
172 | p = valid->root->base + sizeTableOffset; |
||
173 | GXV_LIMIT_CHECK( nSizes * 4 ); |
||
174 | gxv_odtect_add_range( p, nSizes * 4, "sizeTable", odtect ); |
||
175 | |||
176 | /* validate trackValueOffet */ |
||
177 | p = valid->root->base + GXV_TRAK_DATA( trackValueOffset_min ); |
||
178 | if ( limit - p < nTracks * nSizes * 2 ) |
||
179 | GXV_TRACE(( "too short trackValue array\n" )); |
||
180 | |||
181 | p = valid->root->base + GXV_TRAK_DATA( trackValueOffset_max ); |
||
182 | GXV_LIMIT_CHECK( nSizes * 2 ); |
||
183 | |||
184 | gxv_odtect_add_range( valid->root->base |
||
185 | + GXV_TRAK_DATA( trackValueOffset_min ), |
||
186 | GXV_TRAK_DATA( trackValueOffset_max ) |
||
187 | - GXV_TRAK_DATA( trackValueOffset_min ) |
||
188 | + nSizes * 2, |
||
189 | "trackValue array", odtect ); |
||
190 | |||
191 | gxv_odtect_validate( odtect, valid ); |
||
192 | |||
193 | GXV_EXIT; |
||
194 | } |
||
195 | |||
196 | |||
197 | /*************************************************************************/ |
||
198 | /*************************************************************************/ |
||
199 | /***** *****/ |
||
200 | /***** trak TABLE *****/ |
||
201 | /***** *****/ |
||
202 | /*************************************************************************/ |
||
203 | /*************************************************************************/ |
||
204 | |||
205 | FT_LOCAL_DEF( void ) |
||
206 | gxv_trak_validate( FT_Bytes table, |
||
207 | FT_Face face, |
||
208 | FT_Validator ftvalid ) |
||
209 | { |
||
210 | FT_Bytes p = table; |
||
211 | FT_Bytes limit = 0; |
||
212 | |||
213 | GXV_ValidatorRec validrec; |
||
214 | GXV_Validator valid = &validrec; |
||
215 | GXV_trak_DataRec trakrec; |
||
216 | GXV_trak_Data trak = &trakrec; |
||
217 | |||
218 | FT_ULong version; |
||
219 | FT_UShort format; |
||
220 | FT_UShort horizOffset; |
||
221 | FT_UShort vertOffset; |
||
222 | FT_UShort reserved; |
||
223 | |||
224 | |||
225 | GXV_ODTECT( 3, odtect ); |
||
226 | |||
227 | GXV_ODTECT_INIT( odtect ); |
||
228 | valid->root = ftvalid; |
||
229 | valid->table_data = trak; |
||
230 | valid->face = face; |
||
231 | |||
232 | limit = valid->root->limit; |
||
233 | |||
234 | FT_TRACE3(( "validating `trak' table\n" )); |
||
235 | GXV_INIT; |
||
236 | |||
237 | GXV_LIMIT_CHECK( 4 + 2 + 2 + 2 + 2 ); |
||
238 | version = FT_NEXT_ULONG( p ); |
||
239 | format = FT_NEXT_USHORT( p ); |
||
240 | horizOffset = FT_NEXT_USHORT( p ); |
||
241 | vertOffset = FT_NEXT_USHORT( p ); |
||
242 | reserved = FT_NEXT_USHORT( p ); |
||
243 | |||
244 | GXV_TRACE(( " (version = 0x%08x)\n", version )); |
||
245 | GXV_TRACE(( " (format = 0x%04x)\n", format )); |
||
246 | GXV_TRACE(( " (horizOffset = 0x%04x)\n", horizOffset )); |
||
247 | GXV_TRACE(( " (vertOffset = 0x%04x)\n", vertOffset )); |
||
248 | GXV_TRACE(( " (reserved = 0x%04x)\n", reserved )); |
||
249 | |||
250 | /* Version 1.0 (always:1996) */ |
||
251 | if ( version != 0x00010000UL ) |
||
252 | FT_INVALID_FORMAT; |
||
253 | |||
254 | /* format 0 (always:1996) */ |
||
255 | if ( format != 0x0000 ) |
||
256 | FT_INVALID_FORMAT; |
||
257 | |||
258 | GXV_32BIT_ALIGNMENT_VALIDATE( horizOffset ); |
||
259 | GXV_32BIT_ALIGNMENT_VALIDATE( vertOffset ); |
||
260 | |||
261 | /* Reserved Fixed Value (always) */ |
||
262 | if ( reserved != 0x0000 ) |
||
263 | FT_INVALID_DATA; |
||
264 | |||
265 | /* validate trackData */ |
||
266 | if ( 0 < horizOffset ) |
||
267 | { |
||
268 | gxv_trak_trackData_validate( table + horizOffset, limit, valid ); |
||
269 | gxv_odtect_add_range( table + horizOffset, valid->subtable_length, |
||
270 | "horizJustData", odtect ); |
||
271 | } |
||
272 | |||
273 | if ( 0 < vertOffset ) |
||
274 | { |
||
275 | gxv_trak_trackData_validate( table + vertOffset, limit, valid ); |
||
276 | gxv_odtect_add_range( table + vertOffset, valid->subtable_length, |
||
277 | "vertJustData", odtect ); |
||
278 | } |
||
279 | |||
280 | gxv_odtect_validate( odtect, valid ); |
||
281 | |||
282 | FT_TRACE4(( "\n" )); |
||
283 | } |
||
284 | |||
285 | |||
286 | /* END */>>>>>> |