00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "gxvalid.h"
00028 #include "gxvcommn.h"
00029
00030
00031
00032
00033
00034
00035
00036
00037 #undef FT_COMPONENT
00038 #define FT_COMPONENT trace_gxvtrak
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 typedef struct GXV_trak_DataRec_
00074 {
00075 FT_UShort trackValueOffset_min;
00076 FT_UShort trackValueOffset_max;
00077
00078 } GXV_trak_DataRec, *GXV_trak_Data;
00079
00080
00081 #define GXV_TRAK_DATA( FIELD ) GXV_TABLE_DATA( trak, FIELD )
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092 static void
00093 gxv_trak_trackTable_validate( FT_Bytes table,
00094 FT_Bytes limit,
00095 FT_UShort nTracks,
00096 GXV_Validator valid )
00097 {
00098 FT_Bytes p = table;
00099
00100 FT_Fixed track;
00101 FT_UShort nameIndex;
00102 FT_UShort offset;
00103 FT_UShort i;
00104
00105
00106 GXV_NAME_ENTER( "trackTable" );
00107
00108 GXV_TRAK_DATA( trackValueOffset_min ) = 0xFFFFU;
00109 GXV_TRAK_DATA( trackValueOffset_max ) = 0x0000;
00110
00111 for ( i = 0; i < nTracks; i ++ )
00112 {
00113 GXV_LIMIT_CHECK( 4 + 2 + 2 );
00114 track = FT_NEXT_LONG( p );
00115 nameIndex = FT_NEXT_USHORT( p );
00116 offset = FT_NEXT_USHORT( p );
00117
00118 if ( offset < GXV_TRAK_DATA( trackValueOffset_min ) )
00119 GXV_TRAK_DATA( trackValueOffset_min ) = offset;
00120 if ( offset > GXV_TRAK_DATA( trackValueOffset_max ) )
00121 GXV_TRAK_DATA( trackValueOffset_max ) = offset;
00122
00123 gxv_sfntName_validate( nameIndex, 256, 32767, valid );
00124 }
00125
00126 valid->subtable_length = p - table;
00127 GXV_EXIT;
00128 }
00129
00130
00131 static void
00132 gxv_trak_trackData_validate( FT_Bytes table,
00133 FT_Bytes limit,
00134 GXV_Validator valid )
00135 {
00136 FT_Bytes p = table;
00137 FT_UShort nTracks;
00138 FT_UShort nSizes;
00139 FT_ULong sizeTableOffset;
00140
00141 GXV_ODTECT( 4, odtect );
00142
00143
00144 GXV_ODTECT_INIT( odtect );
00145 GXV_NAME_ENTER( "trackData" );
00146
00147
00148 GXV_LIMIT_CHECK( 2 + 2 + 4 );
00149 nTracks = FT_NEXT_USHORT( p );
00150 nSizes = FT_NEXT_USHORT( p );
00151 sizeTableOffset = FT_NEXT_ULONG( p );
00152
00153 gxv_odtect_add_range( table, p - table, "trackData header", odtect );
00154
00155
00156 gxv_trak_trackTable_validate( p, limit, nTracks, valid );
00157 gxv_odtect_add_range( p, valid->subtable_length,
00158 "trackTable", odtect );
00159
00160
00161 p = valid->root->base + sizeTableOffset;
00162 GXV_LIMIT_CHECK( nSizes * 4 );
00163 gxv_odtect_add_range( p, nSizes * 4, "sizeTable", odtect );
00164
00165
00166 p = valid->root->base + GXV_TRAK_DATA( trackValueOffset_min );
00167 if ( limit - p < nTracks * nSizes * 2 )
00168 GXV_TRACE(( "too short trackValue array\n" ));
00169
00170 p = valid->root->base + GXV_TRAK_DATA( trackValueOffset_max );
00171 GXV_LIMIT_CHECK( nSizes * 2 );
00172
00173 gxv_odtect_add_range( valid->root->base
00174 + GXV_TRAK_DATA( trackValueOffset_min ),
00175 GXV_TRAK_DATA( trackValueOffset_max )
00176 - GXV_TRAK_DATA( trackValueOffset_min )
00177 + nSizes * 2,
00178 "trackValue array", odtect );
00179
00180 gxv_odtect_validate( odtect, valid );
00181
00182 GXV_EXIT;
00183 }
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194 FT_LOCAL_DEF( void )
00195 gxv_trak_validate( FT_Bytes table,
00196 FT_Face face,
00197 FT_Validator ftvalid )
00198 {
00199 FT_Bytes p = table;
00200 FT_Bytes limit = 0;
00201 FT_Offset table_size;
00202
00203 GXV_ValidatorRec validrec;
00204 GXV_Validator valid = &validrec;
00205 GXV_trak_DataRec trakrec;
00206 GXV_trak_Data trak = &trakrec;
00207
00208 FT_ULong version;
00209 FT_UShort format;
00210 FT_UShort horizOffset;
00211 FT_UShort vertOffset;
00212 FT_UShort reserved;
00213
00214
00215 GXV_ODTECT( 3, odtect );
00216
00217 GXV_ODTECT_INIT( odtect );
00218 valid->root = ftvalid;
00219 valid->table_data = trak;
00220 valid->face = face;
00221
00222 limit = valid->root->limit;
00223 table_size = limit - table;
00224
00225 FT_TRACE3(( "validating `trak' table\n" ));
00226 GXV_INIT;
00227
00228 GXV_LIMIT_CHECK( 4 + 2 + 2 + 2 + 2 );
00229 version = FT_NEXT_ULONG( p );
00230 format = FT_NEXT_USHORT( p );
00231 horizOffset = FT_NEXT_USHORT( p );
00232 vertOffset = FT_NEXT_USHORT( p );
00233 reserved = FT_NEXT_USHORT( p );
00234
00235 GXV_TRACE(( " (version = 0x%08x)\n", version ));
00236 GXV_TRACE(( " (format = 0x%04x)\n", format ));
00237 GXV_TRACE(( " (horizOffset = 0x%04x)\n", horizOffset ));
00238 GXV_TRACE(( " (vertOffset = 0x%04x)\n", vertOffset ));
00239 GXV_TRACE(( " (reserved = 0x%04x)\n", reserved ));
00240
00241
00242 if ( version != 0x00010000UL )
00243 FT_INVALID_FORMAT;
00244
00245
00246 if ( format != 0x0000 )
00247 FT_INVALID_FORMAT;
00248
00249 GXV_32BIT_ALIGNMENT_VALIDATE( horizOffset );
00250 GXV_32BIT_ALIGNMENT_VALIDATE( vertOffset );
00251
00252
00253 if ( reserved != 0x0000 )
00254 FT_INVALID_DATA;
00255
00256
00257 if ( 0 < horizOffset )
00258 {
00259 gxv_trak_trackData_validate( table + horizOffset, limit, valid );
00260 gxv_odtect_add_range( table + horizOffset, valid->subtable_length,
00261 "horizJustData", odtect );
00262 }
00263
00264 if ( 0 < vertOffset )
00265 {
00266 gxv_trak_trackData_validate( table + vertOffset, limit, valid );
00267 gxv_odtect_add_range( table + vertOffset, valid->subtable_length,
00268 "vertJustData", odtect );
00269 }
00270
00271 gxv_odtect_validate( odtect, valid );
00272
00273 FT_TRACE4(( "\n" ));
00274 }
00275
00276
00277