• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
otv_BaseCoord_validate(FT_Bytes table,OTV_Validator otvalid)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
otv_BaseTagList_validate(FT_Bytes table,OTV_Validator otvalid)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
otv_BaseValues_validate(FT_Bytes table,OTV_Validator otvalid)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
otv_MinMax_validate(FT_Bytes table,OTV_Validator otvalid)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
otv_BaseScript_validate(FT_Bytes table,OTV_Validator otvalid)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
otv_BaseScriptList_validate(FT_Bytes table,OTV_Validator otvalid)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
otv_Axis_validate(FT_Bytes table,OTV_Validator otvalid)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 )
otv_BASE_validate(FT_Bytes table,FT_Validator ftvalid)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 */
346