Subversion Repositories Kolibri OS

Rev

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 */