• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /****************************************************************************
2  *
3  * gxvbsln.c
4  *
5  *   TrueTypeGX/AAT bsln table validation (body).
6  *
7  * Copyright (C) 2004-2020 by
8  * suzuki toshiya, Masatake YAMATO, Red Hat K.K.,
9  * David Turner, Robert Wilhelm, and Werner Lemberg.
10  *
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.
16  *
17  */
18 
19 /****************************************************************************
20  *
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.
24  *
25  */
26 
27 
28 #include "gxvalid.h"
29 #include "gxvcommn.h"
30 
31 
32   /**************************************************************************
33    *
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.
37    */
38 #undef  FT_COMPONENT
39 #define FT_COMPONENT  gxvbsln
40 
41 
42   /*************************************************************************/
43   /*************************************************************************/
44   /*****                                                               *****/
45   /*****                      Data and Types                           *****/
46   /*****                                                               *****/
47   /*************************************************************************/
48   /*************************************************************************/
49 
50 #define GXV_BSLN_VALUE_COUNT  32
51 #define GXV_BSLN_VALUE_EMPTY  0xFFFFU
52 
53 
54   typedef struct  GXV_bsln_DataRec_
55   {
56     FT_Bytes   ctlPoints_p;
57     FT_UShort  defaultBaseline;
58 
59   } GXV_bsln_DataRec, *GXV_bsln_Data;
60 
61 
62 #define GXV_BSLN_DATA( field )  GXV_TABLE_DATA( bsln, field )
63 
64 
65   /*************************************************************************/
66   /*************************************************************************/
67   /*****                                                               *****/
68   /*****                      UTILITY FUNCTIONS                        *****/
69   /*****                                                               *****/
70   /*************************************************************************/
71   /*************************************************************************/
72 
73   static void
gxv_bsln_LookupValue_validate(FT_UShort glyph,GXV_LookupValueCPtr value_p,GXV_Validator gxvalid)74   gxv_bsln_LookupValue_validate( FT_UShort            glyph,
75                                  GXV_LookupValueCPtr  value_p,
76                                  GXV_Validator        gxvalid )
77   {
78     FT_UShort     v = value_p->u;
79     FT_UShort*    ctlPoints;
80 
81     FT_UNUSED( glyph );
82 
83 
84     GXV_NAME_ENTER( "lookup value" );
85 
86     if ( v >= GXV_BSLN_VALUE_COUNT )
87       FT_INVALID_DATA;
88 
89     ctlPoints = (FT_UShort*)GXV_BSLN_DATA( ctlPoints_p );
90     if ( ctlPoints && ctlPoints[v] == GXV_BSLN_VALUE_EMPTY )
91       FT_INVALID_DATA;
92 
93     GXV_EXIT;
94   }
95 
96 
97   /*
98     +===============+ --------+
99     | lookup header |         |
100     +===============+         |
101     | BinSrchHeader |         |
102     +===============+         |
103     | lastGlyph[0]  |         |
104     +---------------+         |
105     | firstGlyph[0] |         |    head of lookup table
106     +---------------+         |             +
107     | offset[0]     |    ->   |          offset            [byte]
108     +===============+         |             +
109     | lastGlyph[1]  |         | (glyphID - firstGlyph) * 2 [byte]
110     +---------------+         |
111     | firstGlyph[1] |         |
112     +---------------+         |
113     | offset[1]     |         |
114     +===============+         |
115                               |
116     ...                       |
117                               |
118     16bit value array         |
119     +===============+         |
120     |     value     | <-------+
121     ...
122   */
123 
124   static GXV_LookupValueDesc
gxv_bsln_LookupFmt4_transit(FT_UShort relative_gindex,GXV_LookupValueCPtr base_value_p,FT_Bytes lookuptbl_limit,GXV_Validator gxvalid)125   gxv_bsln_LookupFmt4_transit( FT_UShort            relative_gindex,
126                                GXV_LookupValueCPtr  base_value_p,
127                                FT_Bytes             lookuptbl_limit,
128                                GXV_Validator        gxvalid )
129   {
130     FT_Bytes             p;
131     FT_Bytes             limit;
132     FT_UShort            offset;
133     GXV_LookupValueDesc  value;
134 
135     /* XXX: check range ? */
136     offset = (FT_UShort)( base_value_p->u +
137                           ( relative_gindex * sizeof ( FT_UShort ) ) );
138 
139     p     = gxvalid->lookuptbl_head + offset;
140     limit = lookuptbl_limit;
141     GXV_LIMIT_CHECK( 2 );
142 
143     value.u = FT_NEXT_USHORT( p );
144 
145     return value;
146   }
147 
148 
149   static void
gxv_bsln_parts_fmt0_validate(FT_Bytes tables,FT_Bytes limit,GXV_Validator gxvalid)150   gxv_bsln_parts_fmt0_validate( FT_Bytes       tables,
151                                 FT_Bytes       limit,
152                                 GXV_Validator  gxvalid )
153   {
154     FT_Bytes  p = tables;
155 
156 
157     GXV_NAME_ENTER( "parts format 0" );
158 
159     /* deltas */
160     GXV_LIMIT_CHECK( 2 * GXV_BSLN_VALUE_COUNT );
161 
162     gxvalid->table_data = NULL;      /* No ctlPoints here. */
163 
164     GXV_EXIT;
165   }
166 
167 
168   static void
gxv_bsln_parts_fmt1_validate(FT_Bytes tables,FT_Bytes limit,GXV_Validator gxvalid)169   gxv_bsln_parts_fmt1_validate( FT_Bytes       tables,
170                                 FT_Bytes       limit,
171                                 GXV_Validator  gxvalid )
172   {
173     FT_Bytes  p = tables;
174 
175 
176     GXV_NAME_ENTER( "parts format 1" );
177 
178     /* deltas */
179     gxv_bsln_parts_fmt0_validate( p, limit, gxvalid );
180 
181     /* mappingData */
182     gxvalid->lookupval_sign   = GXV_LOOKUPVALUE_UNSIGNED;
183     gxvalid->lookupval_func   = gxv_bsln_LookupValue_validate;
184     gxvalid->lookupfmt4_trans = gxv_bsln_LookupFmt4_transit;
185     gxv_LookupTable_validate( p + 2 * GXV_BSLN_VALUE_COUNT,
186                               limit,
187                               gxvalid );
188 
189     GXV_EXIT;
190   }
191 
192 
193   static void
gxv_bsln_parts_fmt2_validate(FT_Bytes tables,FT_Bytes limit,GXV_Validator gxvalid)194   gxv_bsln_parts_fmt2_validate( FT_Bytes       tables,
195                                 FT_Bytes       limit,
196                                 GXV_Validator  gxvalid )
197   {
198     FT_Bytes   p = tables;
199 
200     FT_UShort  stdGlyph;
201     FT_UShort  ctlPoint;
202     FT_Int     i;
203 
204     FT_UShort  defaultBaseline = GXV_BSLN_DATA( defaultBaseline );
205 
206 
207     GXV_NAME_ENTER( "parts format 2" );
208 
209     GXV_LIMIT_CHECK( 2 + ( 2 * GXV_BSLN_VALUE_COUNT ) );
210 
211     /* stdGlyph */
212     stdGlyph = FT_NEXT_USHORT( p );
213     GXV_TRACE(( " (stdGlyph = %u)\n", stdGlyph ));
214 
215     gxv_glyphid_validate( stdGlyph, gxvalid );
216 
217     /* Record the position of ctlPoints */
218     GXV_BSLN_DATA( ctlPoints_p ) = p;
219 
220     /* ctlPoints */
221     for ( i = 0; i < GXV_BSLN_VALUE_COUNT; i++ )
222     {
223       ctlPoint = FT_NEXT_USHORT( p );
224       if ( ctlPoint == GXV_BSLN_VALUE_EMPTY )
225       {
226         if ( i == defaultBaseline )
227           FT_INVALID_DATA;
228       }
229       else
230         gxv_ctlPoint_validate( stdGlyph, ctlPoint, gxvalid );
231     }
232 
233     GXV_EXIT;
234   }
235 
236 
237   static void
gxv_bsln_parts_fmt3_validate(FT_Bytes tables,FT_Bytes limit,GXV_Validator gxvalid)238   gxv_bsln_parts_fmt3_validate( FT_Bytes       tables,
239                                 FT_Bytes       limit,
240                                 GXV_Validator  gxvalid)
241   {
242     FT_Bytes  p = tables;
243 
244 
245     GXV_NAME_ENTER( "parts format 3" );
246 
247     /* stdGlyph + ctlPoints */
248     gxv_bsln_parts_fmt2_validate( p, limit, gxvalid );
249 
250     /* mappingData */
251     gxvalid->lookupval_sign   = GXV_LOOKUPVALUE_UNSIGNED;
252     gxvalid->lookupval_func   = gxv_bsln_LookupValue_validate;
253     gxvalid->lookupfmt4_trans = gxv_bsln_LookupFmt4_transit;
254     gxv_LookupTable_validate( p + ( 2 + 2 * GXV_BSLN_VALUE_COUNT ),
255                               limit,
256                               gxvalid );
257 
258     GXV_EXIT;
259   }
260 
261 
262   /*************************************************************************/
263   /*************************************************************************/
264   /*****                                                               *****/
265   /*****                         bsln TABLE                            *****/
266   /*****                                                               *****/
267   /*************************************************************************/
268   /*************************************************************************/
269 
270   FT_LOCAL_DEF( void )
gxv_bsln_validate(FT_Bytes table,FT_Face face,FT_Validator ftvalid)271   gxv_bsln_validate( FT_Bytes      table,
272                      FT_Face       face,
273                      FT_Validator  ftvalid )
274   {
275     GXV_ValidatorRec  gxvalidrec;
276     GXV_Validator     gxvalid = &gxvalidrec;
277 
278     GXV_bsln_DataRec  bslnrec;
279     GXV_bsln_Data     bsln = &bslnrec;
280 
281     FT_Bytes  p     = table;
282     FT_Bytes  limit = 0;
283 
284     FT_ULong   version;
285     FT_UShort  format;
286     FT_UShort  defaultBaseline;
287 
288     GXV_Validate_Func  fmt_funcs_table [] =
289     {
290       gxv_bsln_parts_fmt0_validate,
291       gxv_bsln_parts_fmt1_validate,
292       gxv_bsln_parts_fmt2_validate,
293       gxv_bsln_parts_fmt3_validate,
294     };
295 
296 
297     gxvalid->root       = ftvalid;
298     gxvalid->table_data = bsln;
299     gxvalid->face       = face;
300 
301     FT_TRACE3(( "validating `bsln' table\n" ));
302     GXV_INIT;
303 
304 
305     GXV_LIMIT_CHECK( 4 + 2 + 2 );
306     version         = FT_NEXT_ULONG( p );
307     format          = FT_NEXT_USHORT( p );
308     defaultBaseline = FT_NEXT_USHORT( p );
309 
310     /* only version 1.0 is defined (1996) */
311     if ( version != 0x00010000UL )
312       FT_INVALID_FORMAT;
313 
314     /* only format 1, 2, 3 are defined (1996) */
315     GXV_TRACE(( " (format = %d)\n", format ));
316     if ( format > 3 )
317       FT_INVALID_FORMAT;
318 
319     if ( defaultBaseline > 31 )
320       FT_INVALID_FORMAT;
321 
322     bsln->defaultBaseline = defaultBaseline;
323 
324     fmt_funcs_table[format]( p, limit, gxvalid );
325 
326     FT_TRACE4(( "\n" ));
327   }
328 
329 
330 /* arch-tag: ebe81143-fdaa-4c68-a4d1-b57227daa3bc
331    (do not change this comment) */
332 
333 
334 /* END */
335