Git init
[framework/graphics/freetype.git] / src / gxvalid / gxvtrak.c
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;
101     FT_UShort  nameIndex;
102     FT_UShort  offset;
103     FT_UShort  i;
104
105
106     GXV_NAME_ENTER( "trackTable" );
107
108     GXV_TRAK_DATA( trackValueOffset_min ) = 0xFFFFU;
109     GXV_TRAK_DATA( trackValueOffset_max ) = 0x0000;
110
111     for ( i = 0; i < nTracks; i ++ )
112     {
113       GXV_LIMIT_CHECK( 4 + 2 + 2 );
114       track     = FT_NEXT_LONG( p );
115       nameIndex = FT_NEXT_USHORT( p );
116       offset    = FT_NEXT_USHORT( p );
117
118       if ( offset < GXV_TRAK_DATA( trackValueOffset_min ) )
119         GXV_TRAK_DATA( trackValueOffset_min ) = offset;
120       if ( offset > GXV_TRAK_DATA( trackValueOffset_max ) )
121         GXV_TRAK_DATA( trackValueOffset_max ) = offset;
122
123       gxv_sfntName_validate( nameIndex, 256, 32767, valid );
124     }
125
126     valid->subtable_length = p - table;
127     GXV_EXIT;
128   }
129
130
131   static void
132   gxv_trak_trackData_validate( FT_Bytes       table,
133                                FT_Bytes       limit,
134                                GXV_Validator  valid )
135   {
136     FT_Bytes   p = table;
137     FT_UShort  nTracks;
138     FT_UShort  nSizes;
139     FT_ULong   sizeTableOffset;
140
141     GXV_ODTECT( 4, odtect );
142
143
144     GXV_ODTECT_INIT( odtect );
145     GXV_NAME_ENTER( "trackData" );
146
147     /* read the header of trackData */
148     GXV_LIMIT_CHECK( 2 + 2 + 4 );
149     nTracks         = FT_NEXT_USHORT( p );
150     nSizes          = FT_NEXT_USHORT( p );
151     sizeTableOffset = FT_NEXT_ULONG( p );
152
153     gxv_odtect_add_range( table, p - table, "trackData header", odtect );
154
155     /* validate trackTable */
156     gxv_trak_trackTable_validate( p, limit, nTracks, valid );
157     gxv_odtect_add_range( p, valid->subtable_length,
158                           "trackTable", odtect );
159
160     /* sizeTable is array of FT_Fixed, don't check contents */
161     p = valid->root->base + sizeTableOffset;
162     GXV_LIMIT_CHECK( nSizes * 4 );
163     gxv_odtect_add_range( p, nSizes * 4, "sizeTable", odtect );
164
165     /* validate trackValueOffet */
166     p = valid->root->base + GXV_TRAK_DATA( trackValueOffset_min );
167     if ( limit - p < nTracks * nSizes * 2 )
168       GXV_TRACE(( "too short trackValue array\n" ));
169
170     p = valid->root->base + GXV_TRAK_DATA( trackValueOffset_max );
171     GXV_LIMIT_CHECK( nSizes * 2 );
172
173     gxv_odtect_add_range( valid->root->base
174                             + GXV_TRAK_DATA( trackValueOffset_min ),
175                           GXV_TRAK_DATA( trackValueOffset_max )
176                             - GXV_TRAK_DATA( trackValueOffset_min )
177                             + nSizes * 2,
178                           "trackValue array", odtect );
179
180     gxv_odtect_validate( odtect, valid );
181
182     GXV_EXIT;
183   }
184
185
186   /*************************************************************************/
187   /*************************************************************************/
188   /*****                                                               *****/
189   /*****                          trak TABLE                           *****/
190   /*****                                                               *****/
191   /*************************************************************************/
192   /*************************************************************************/
193
194   FT_LOCAL_DEF( void )
195   gxv_trak_validate( FT_Bytes      table,
196                      FT_Face       face,
197                      FT_Validator  ftvalid )
198   {
199     FT_Bytes          p = table;
200     FT_Bytes          limit = 0;
201     FT_Offset         table_size;
202
203     GXV_ValidatorRec  validrec;
204     GXV_Validator     valid = &validrec;
205     GXV_trak_DataRec  trakrec;
206     GXV_trak_Data     trak = &trakrec;
207
208     FT_ULong   version;
209     FT_UShort  format;
210     FT_UShort  horizOffset;
211     FT_UShort  vertOffset;
212     FT_UShort  reserved;
213
214
215     GXV_ODTECT( 3, odtect );
216
217     GXV_ODTECT_INIT( odtect );
218     valid->root       = ftvalid;
219     valid->table_data = trak;
220     valid->face       = face;
221
222     limit      = valid->root->limit;
223     table_size = limit - table;
224
225     FT_TRACE3(( "validating `trak' table\n" ));
226     GXV_INIT;
227
228     GXV_LIMIT_CHECK( 4 + 2 + 2 + 2 + 2 );
229     version     = FT_NEXT_ULONG( p );
230     format      = FT_NEXT_USHORT( p );
231     horizOffset = FT_NEXT_USHORT( p );
232     vertOffset  = FT_NEXT_USHORT( p );
233     reserved    = FT_NEXT_USHORT( p );
234
235     GXV_TRACE(( " (version = 0x%08x)\n", version ));
236     GXV_TRACE(( " (format = 0x%04x)\n", format ));
237     GXV_TRACE(( " (horizOffset = 0x%04x)\n", horizOffset ));
238     GXV_TRACE(( " (vertOffset = 0x%04x)\n", vertOffset ));
239     GXV_TRACE(( " (reserved = 0x%04x)\n", reserved ));
240
241     /* Version 1.0 (always:1996) */
242     if ( version != 0x00010000UL )
243       FT_INVALID_FORMAT;
244
245     /* format 0 (always:1996) */
246     if ( format != 0x0000 )
247       FT_INVALID_FORMAT;
248
249     GXV_32BIT_ALIGNMENT_VALIDATE( horizOffset );
250     GXV_32BIT_ALIGNMENT_VALIDATE( vertOffset );
251
252     /* Reserved Fixed Value (always) */
253     if ( reserved != 0x0000 )
254       FT_INVALID_DATA;
255
256     /* validate trackData */
257     if ( 0 < horizOffset )
258     {
259       gxv_trak_trackData_validate( table + horizOffset, limit, valid );
260       gxv_odtect_add_range( table + horizOffset, valid->subtable_length,
261                             "horizJustData", odtect );
262     }
263
264     if ( 0 < vertOffset )
265     {
266       gxv_trak_trackData_validate( table + vertOffset, limit, valid );
267       gxv_odtect_add_range( table + vertOffset, valid->subtable_length,
268                             "vertJustData", odtect );
269     }
270
271     gxv_odtect_validate( odtect, valid );
272
273     FT_TRACE4(( "\n" ));
274   }
275
276
277 /* END */