Imported Upstream version 2.10.4
[platform/upstream/freetype2.git] / src / otvalid / otvbase.c
1 /****************************************************************************
2  *
3  * otvbase.c
4  *
5  *   OpenType BASE table validation (body).
6  *
7  * Copyright (C) 2004-2020 by
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 #include "otvalid.h"
20 #include "otvcommn.h"
21
22
23   /**************************************************************************
24    *
25    * The macro FT_COMPONENT is used in trace mode.  It is an implicit
26    * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
27    * messages during execution.
28    */
29 #undef  FT_COMPONENT
30 #define FT_COMPONENT  otvbase
31
32
33   static void
34   otv_BaseCoord_validate( FT_Bytes       table,
35                           OTV_Validator  otvalid )
36   {
37     FT_Bytes  p = table;
38     FT_UInt   BaseCoordFormat;
39
40
41     OTV_NAME_ENTER( "BaseCoord" );
42
43     OTV_LIMIT_CHECK( 4 );
44     BaseCoordFormat = FT_NEXT_USHORT( p );
45     p += 2;     /* skip Coordinate */
46
47     OTV_TRACE(( " (format %d)\n", BaseCoordFormat ));
48
49     switch ( BaseCoordFormat )
50     {
51     case 1:     /* BaseCoordFormat1 */
52       break;
53
54     case 2:     /* BaseCoordFormat2 */
55       OTV_LIMIT_CHECK( 4 );   /* ReferenceGlyph, BaseCoordPoint */
56       break;
57
58     case 3:     /* BaseCoordFormat3 */
59       OTV_LIMIT_CHECK( 2 );
60       /* DeviceTable */
61       otv_Device_validate( table + FT_NEXT_USHORT( p ), otvalid );
62       break;
63
64     default:
65       FT_INVALID_FORMAT;
66     }
67
68     OTV_EXIT;
69   }
70
71
72   static void
73   otv_BaseTagList_validate( FT_Bytes       table,
74                             OTV_Validator  otvalid )
75   {
76     FT_Bytes  p = table;
77     FT_UInt   BaseTagCount;
78
79
80     OTV_NAME_ENTER( "BaseTagList" );
81
82     OTV_LIMIT_CHECK( 2 );
83
84     BaseTagCount = FT_NEXT_USHORT( p );
85
86     OTV_TRACE(( " (BaseTagCount = %d)\n", BaseTagCount ));
87
88     OTV_LIMIT_CHECK( BaseTagCount * 4 );          /* BaselineTag */
89
90     OTV_EXIT;
91   }
92
93
94   static void
95   otv_BaseValues_validate( FT_Bytes       table,
96                            OTV_Validator  otvalid )
97   {
98     FT_Bytes  p = table;
99     FT_UInt   BaseCoordCount;
100
101
102     OTV_NAME_ENTER( "BaseValues" );
103
104     OTV_LIMIT_CHECK( 4 );
105
106     p             += 2;                     /* skip DefaultIndex */
107     BaseCoordCount = FT_NEXT_USHORT( p );
108
109     OTV_TRACE(( " (BaseCoordCount = %d)\n", BaseCoordCount ));
110
111     OTV_LIMIT_CHECK( BaseCoordCount * 2 );
112
113     /* BaseCoord */
114     for ( ; BaseCoordCount > 0; BaseCoordCount-- )
115       otv_BaseCoord_validate( table + FT_NEXT_USHORT( p ), otvalid );
116
117     OTV_EXIT;
118   }
119
120
121   static void
122   otv_MinMax_validate( FT_Bytes       table,
123                        OTV_Validator  otvalid )
124   {
125     FT_Bytes  p = table;
126     FT_UInt   table_size;
127     FT_UInt   FeatMinMaxCount;
128
129     OTV_OPTIONAL_TABLE( MinCoord );
130     OTV_OPTIONAL_TABLE( MaxCoord );
131
132
133     OTV_NAME_ENTER( "MinMax" );
134
135     OTV_LIMIT_CHECK( 6 );
136
137     OTV_OPTIONAL_OFFSET( MinCoord );
138     OTV_OPTIONAL_OFFSET( MaxCoord );
139     FeatMinMaxCount = FT_NEXT_USHORT( p );
140
141     OTV_TRACE(( " (FeatMinMaxCount = %d)\n", FeatMinMaxCount ));
142
143     table_size = FeatMinMaxCount * 8 + 6;
144
145     OTV_SIZE_CHECK( MinCoord );
146     if ( MinCoord )
147       otv_BaseCoord_validate( table + MinCoord, otvalid );
148
149     OTV_SIZE_CHECK( MaxCoord );
150     if ( MaxCoord )
151       otv_BaseCoord_validate( table + MaxCoord, otvalid );
152
153     OTV_LIMIT_CHECK( FeatMinMaxCount * 8 );
154
155     /* FeatMinMaxRecord */
156     for ( ; FeatMinMaxCount > 0; FeatMinMaxCount-- )
157     {
158       p += 4;                           /* skip FeatureTableTag */
159
160       OTV_OPTIONAL_OFFSET( MinCoord );
161       OTV_OPTIONAL_OFFSET( MaxCoord );
162
163       OTV_SIZE_CHECK( MinCoord );
164       if ( MinCoord )
165         otv_BaseCoord_validate( table + MinCoord, otvalid );
166
167       OTV_SIZE_CHECK( MaxCoord );
168       if ( MaxCoord )
169         otv_BaseCoord_validate( table + MaxCoord, otvalid );
170     }
171
172     OTV_EXIT;
173   }
174
175
176   static void
177   otv_BaseScript_validate( FT_Bytes       table,
178                            OTV_Validator  otvalid )
179   {
180     FT_Bytes  p = table;
181     FT_UInt   table_size;
182     FT_UInt   BaseLangSysCount;
183
184     OTV_OPTIONAL_TABLE( BaseValues    );
185     OTV_OPTIONAL_TABLE( DefaultMinMax );
186
187
188     OTV_NAME_ENTER( "BaseScript" );
189
190     OTV_LIMIT_CHECK( 6 );
191     OTV_OPTIONAL_OFFSET( BaseValues    );
192     OTV_OPTIONAL_OFFSET( DefaultMinMax );
193     BaseLangSysCount = FT_NEXT_USHORT( p );
194
195     OTV_TRACE(( " (BaseLangSysCount = %d)\n", BaseLangSysCount ));
196
197     table_size = BaseLangSysCount * 6 + 6;
198
199     OTV_SIZE_CHECK( BaseValues );
200     if ( BaseValues )
201       otv_BaseValues_validate( table + BaseValues, otvalid );
202
203     OTV_SIZE_CHECK( DefaultMinMax );
204     if ( DefaultMinMax )
205       otv_MinMax_validate( table + DefaultMinMax, otvalid );
206
207     OTV_LIMIT_CHECK( BaseLangSysCount * 6 );
208
209     /* BaseLangSysRecord */
210     for ( ; BaseLangSysCount > 0; BaseLangSysCount-- )
211     {
212       p += 4;       /* skip BaseLangSysTag */
213
214       otv_MinMax_validate( table + FT_NEXT_USHORT( p ), otvalid );
215     }
216
217     OTV_EXIT;
218   }
219
220
221   static void
222   otv_BaseScriptList_validate( FT_Bytes       table,
223                                OTV_Validator  otvalid )
224   {
225     FT_Bytes  p = table;
226     FT_UInt   BaseScriptCount;
227
228
229     OTV_NAME_ENTER( "BaseScriptList" );
230
231     OTV_LIMIT_CHECK( 2 );
232     BaseScriptCount = FT_NEXT_USHORT( p );
233
234     OTV_TRACE(( " (BaseScriptCount = %d)\n", BaseScriptCount ));
235
236     OTV_LIMIT_CHECK( BaseScriptCount * 6 );
237
238     /* BaseScriptRecord */
239     for ( ; BaseScriptCount > 0; BaseScriptCount-- )
240     {
241       p += 4;       /* skip BaseScriptTag */
242
243       /* BaseScript */
244       otv_BaseScript_validate( table + FT_NEXT_USHORT( p ), otvalid );
245     }
246
247     OTV_EXIT;
248   }
249
250
251   static void
252   otv_Axis_validate( FT_Bytes       table,
253                      OTV_Validator  otvalid )
254   {
255     FT_Bytes  p = table;
256     FT_UInt   table_size;
257
258     OTV_OPTIONAL_TABLE( BaseTagList );
259
260
261     OTV_NAME_ENTER( "Axis" );
262
263     OTV_LIMIT_CHECK( 4 );
264     OTV_OPTIONAL_OFFSET( BaseTagList );
265
266     table_size = 4;
267
268     OTV_SIZE_CHECK( BaseTagList );
269     if ( BaseTagList )
270       otv_BaseTagList_validate( table + BaseTagList, otvalid );
271
272     /* BaseScriptList */
273     otv_BaseScriptList_validate( table + FT_NEXT_USHORT( p ), otvalid );
274
275     OTV_EXIT;
276   }
277
278
279   FT_LOCAL_DEF( void )
280   otv_BASE_validate( FT_Bytes      table,
281                      FT_Validator  ftvalid )
282   {
283     OTV_ValidatorRec  otvalidrec;
284     OTV_Validator     otvalid = &otvalidrec;
285     FT_Bytes          p       = table;
286     FT_UInt           table_size;
287     FT_UShort         version;
288
289     OTV_OPTIONAL_TABLE( HorizAxis );
290     OTV_OPTIONAL_TABLE( VertAxis  );
291
292     OTV_OPTIONAL_TABLE32( itemVarStore );
293
294
295     otvalid->root = ftvalid;
296
297     FT_TRACE3(( "validating BASE table\n" ));
298     OTV_INIT;
299
300     OTV_LIMIT_CHECK( 4 );
301
302     if ( FT_NEXT_USHORT( p ) != 1 )  /* majorVersion */
303       FT_INVALID_FORMAT;
304
305     version = FT_NEXT_USHORT( p );   /* minorVersion */
306
307     table_size = 8;
308     switch ( version )
309     {
310     case 0:
311       OTV_LIMIT_CHECK( 4 );
312       break;
313
314     case 1:
315       OTV_LIMIT_CHECK( 8 );
316       table_size += 4;
317       break;
318
319     default:
320       FT_INVALID_FORMAT;
321     }
322
323     OTV_OPTIONAL_OFFSET( HorizAxis );
324     OTV_SIZE_CHECK( HorizAxis );
325     if ( HorizAxis )
326       otv_Axis_validate( table + HorizAxis, otvalid );
327
328     OTV_OPTIONAL_OFFSET( VertAxis );
329     OTV_SIZE_CHECK( VertAxis );
330     if ( VertAxis )
331       otv_Axis_validate( table + VertAxis, otvalid );
332
333     if ( version > 0 )
334     {
335       OTV_OPTIONAL_OFFSET32( itemVarStore );
336       OTV_SIZE_CHECK32( itemVarStore );
337       if ( itemVarStore )
338         OTV_TRACE(( "  [omitting itemVarStore validation]\n" )); /* XXX */
339     }
340
341     FT_TRACE4(( "\n" ));
342   }
343
344
345 /* END */