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