1 /****************************************************************************
5 * TrueTypeGX/AAT trak table validation (body).
7 * Copyright (C) 2004-2020 by
8 * suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
9 * David Turner, Robert Wilhelm, and Werner Lemberg.
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.
19 /****************************************************************************
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.
32 /**************************************************************************
34 * The macro FT_COMPONENT is used in trace mode. It is an implicit
35 * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
36 * messages during execution.
39 #define FT_COMPONENT gxvtrak
42 /*************************************************************************/
43 /*************************************************************************/
45 /***** Data and Types *****/
47 /*************************************************************************/
48 /*************************************************************************/
51 * referred track table format specification:
52 * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6trak.html
53 * last update was 1996.
54 * ----------------------------------------------
55 * [MINIMUM HEADER]: GXV_TRAK_SIZE_MIN
56 * version (fixed: 32bit) = 0x00010000
57 * format (uint16: 16bit) = 0 is only defined (1996)
58 * horizOffset (uint16: 16bit)
59 * vertOffset (uint16: 16bit)
60 * reserved (uint16: 16bit) = 0
61 * ----------------------------------------------
65 * trackTable + nTracks * ( 4 + 2 + 2 )
66 * sizeTable + nSizes * 4 )
67 * ----------------------------------------------
70 * trackTable + nTracks * ( 4 + 2 + 2 )
71 * sizeTable + nSizes * 4 )
72 * ----------------------------------------------
74 typedef struct GXV_trak_DataRec_
76 FT_UShort trackValueOffset_min;
77 FT_UShort trackValueOffset_max;
79 } GXV_trak_DataRec, *GXV_trak_Data;
82 #define GXV_TRAK_DATA( FIELD ) GXV_TABLE_DATA( trak, FIELD )
85 /*************************************************************************/
86 /*************************************************************************/
88 /***** UTILITY FUNCTIONS *****/
90 /*************************************************************************/
91 /*************************************************************************/
94 gxv_trak_trackTable_validate( FT_Bytes table,
97 GXV_Validator gxvalid )
107 GXV_NAME_ENTER( "trackTable" );
109 GXV_TRAK_DATA( trackValueOffset_min ) = 0xFFFFU;
110 GXV_TRAK_DATA( trackValueOffset_max ) = 0x0000;
112 GXV_LIMIT_CHECK( nTracks * ( 4 + 2 + 2 ) );
114 for ( i = 0; i < nTracks; i++ )
116 p = table + i * ( 4 + 2 + 2 );
117 track = FT_NEXT_LONG( p );
118 nameIndex = FT_NEXT_USHORT( p );
119 offset = FT_NEXT_USHORT( p );
121 if ( offset < GXV_TRAK_DATA( trackValueOffset_min ) )
122 GXV_TRAK_DATA( trackValueOffset_min ) = offset;
123 if ( offset > GXV_TRAK_DATA( trackValueOffset_max ) )
124 GXV_TRAK_DATA( trackValueOffset_max ) = offset;
126 gxv_sfntName_validate( nameIndex, 256, 32767, gxvalid );
128 for ( j = i; j < nTracks; j++ )
130 p = table + j * ( 4 + 2 + 2 );
131 t = FT_NEXT_LONG( p );
133 GXV_TRACE(( "duplicated entries found for track value 0x%x\n",
138 gxvalid->subtable_length = (FT_ULong)( p - table );
144 gxv_trak_trackData_validate( FT_Bytes table,
146 GXV_Validator gxvalid )
151 FT_ULong sizeTableOffset;
153 GXV_ODTECT( 4, odtect );
156 GXV_ODTECT_INIT( odtect );
157 GXV_NAME_ENTER( "trackData" );
159 /* read the header of trackData */
160 GXV_LIMIT_CHECK( 2 + 2 + 4 );
161 nTracks = FT_NEXT_USHORT( p );
162 nSizes = FT_NEXT_USHORT( p );
163 sizeTableOffset = FT_NEXT_ULONG( p );
165 gxv_odtect_add_range( table, (FT_ULong)( p - table ),
166 "trackData header", odtect );
168 /* validate trackTable */
169 gxv_trak_trackTable_validate( p, limit, nTracks, gxvalid );
170 gxv_odtect_add_range( p, gxvalid->subtable_length,
171 "trackTable", odtect );
173 /* sizeTable is array of FT_Fixed, don't check contents */
174 p = gxvalid->root->base + sizeTableOffset;
175 GXV_LIMIT_CHECK( nSizes * 4 );
176 gxv_odtect_add_range( p, nSizes * 4, "sizeTable", odtect );
178 /* validate trackValueOffet */
179 p = gxvalid->root->base + GXV_TRAK_DATA( trackValueOffset_min );
180 if ( limit - p < nTracks * nSizes * 2 )
181 GXV_TRACE(( "too short trackValue array\n" ));
183 p = gxvalid->root->base + GXV_TRAK_DATA( trackValueOffset_max );
184 GXV_LIMIT_CHECK( nSizes * 2 );
186 gxv_odtect_add_range( gxvalid->root->base
187 + GXV_TRAK_DATA( trackValueOffset_min ),
188 GXV_TRAK_DATA( trackValueOffset_max )
189 - GXV_TRAK_DATA( trackValueOffset_min )
191 "trackValue array", odtect );
193 gxv_odtect_validate( odtect, gxvalid );
199 /*************************************************************************/
200 /*************************************************************************/
202 /***** trak TABLE *****/
204 /*************************************************************************/
205 /*************************************************************************/
208 gxv_trak_validate( FT_Bytes table,
210 FT_Validator ftvalid )
215 GXV_ValidatorRec gxvalidrec;
216 GXV_Validator gxvalid = &gxvalidrec;
217 GXV_trak_DataRec trakrec;
218 GXV_trak_Data trak = &trakrec;
222 FT_UShort horizOffset;
223 FT_UShort vertOffset;
227 GXV_ODTECT( 3, odtect );
229 GXV_ODTECT_INIT( odtect );
230 gxvalid->root = ftvalid;
231 gxvalid->table_data = trak;
232 gxvalid->face = face;
234 limit = gxvalid->root->limit;
236 FT_TRACE3(( "validating `trak' table\n" ));
239 GXV_LIMIT_CHECK( 4 + 2 + 2 + 2 + 2 );
240 version = FT_NEXT_ULONG( p );
241 format = FT_NEXT_USHORT( p );
242 horizOffset = FT_NEXT_USHORT( p );
243 vertOffset = FT_NEXT_USHORT( p );
244 reserved = FT_NEXT_USHORT( p );
246 GXV_TRACE(( " (version = 0x%08x)\n", version ));
247 GXV_TRACE(( " (format = 0x%04x)\n", format ));
248 GXV_TRACE(( " (horizOffset = 0x%04x)\n", horizOffset ));
249 GXV_TRACE(( " (vertOffset = 0x%04x)\n", vertOffset ));
250 GXV_TRACE(( " (reserved = 0x%04x)\n", reserved ));
252 /* Version 1.0 (always:1996) */
253 if ( version != 0x00010000UL )
256 /* format 0 (always:1996) */
257 if ( format != 0x0000 )
260 GXV_32BIT_ALIGNMENT_VALIDATE( horizOffset );
261 GXV_32BIT_ALIGNMENT_VALIDATE( vertOffset );
263 /* Reserved Fixed Value (always) */
264 if ( reserved != 0x0000 )
267 /* validate trackData */
268 if ( 0 < horizOffset )
270 gxv_trak_trackData_validate( table + horizOffset, limit, gxvalid );
271 gxv_odtect_add_range( table + horizOffset, gxvalid->subtable_length,
272 "horizJustData", odtect );
275 if ( 0 < vertOffset )
277 gxv_trak_trackData_validate( table + vertOffset, limit, gxvalid );
278 gxv_odtect_add_range( table + vertOffset, gxvalid->subtable_length,
279 "vertJustData", odtect );
282 gxv_odtect_validate( odtect, gxvalid );