1 /**************************************************************************** 2 * 3 * gxvopbd.c 4 * 5 * TrueTypeGX/AAT opbd table validation (body). 6 * 7 * Copyright 2004-2018 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 trace_gxvopbd 40 41 42 /*************************************************************************/ 43 /*************************************************************************/ 44 /***** *****/ 45 /***** Data and Types *****/ 46 /***** *****/ 47 /*************************************************************************/ 48 /*************************************************************************/ 49 50 typedef struct GXV_opbd_DataRec_ 51 { 52 FT_UShort format; 53 FT_UShort valueOffset_min; 54 55 } GXV_opbd_DataRec, *GXV_opbd_Data; 56 57 58 #define GXV_OPBD_DATA( FIELD ) GXV_TABLE_DATA( opbd, FIELD ) 59 60 61 /*************************************************************************/ 62 /*************************************************************************/ 63 /***** *****/ 64 /***** UTILITY FUNCTIONS *****/ 65 /***** *****/ 66 /*************************************************************************/ 67 /*************************************************************************/ 68 69 static void gxv_opbd_LookupValue_validate(FT_UShort glyph,GXV_LookupValueCPtr value_p,GXV_Validator gxvalid)70 gxv_opbd_LookupValue_validate( FT_UShort glyph, 71 GXV_LookupValueCPtr value_p, 72 GXV_Validator gxvalid ) 73 { 74 /* offset in LookupTable is measured from the head of opbd table */ 75 FT_Bytes p = gxvalid->root->base + value_p->u; 76 FT_Bytes limit = gxvalid->root->limit; 77 FT_Short delta_value; 78 int i; 79 80 81 if ( value_p->u < GXV_OPBD_DATA( valueOffset_min ) ) 82 GXV_OPBD_DATA( valueOffset_min ) = value_p->u; 83 84 for ( i = 0; i < 4; i++ ) 85 { 86 GXV_LIMIT_CHECK( 2 ); 87 delta_value = FT_NEXT_SHORT( p ); 88 89 if ( GXV_OPBD_DATA( format ) ) /* format 1, value is ctrl pt. */ 90 { 91 if ( delta_value == -1 ) 92 continue; 93 94 gxv_ctlPoint_validate( glyph, (FT_UShort)delta_value, gxvalid ); 95 } 96 else /* format 0, value is distance */ 97 continue; 98 } 99 } 100 101 102 /* 103 opbd ---------------------+ 104 | 105 +===============+ | 106 | lookup header | | 107 +===============+ | 108 | BinSrchHeader | | 109 +===============+ | 110 | lastGlyph[0] | | 111 +---------------+ | 112 | firstGlyph[0] | | head of opbd sfnt table 113 +---------------+ | + 114 | offset[0] | -> | offset [byte] 115 +===============+ | + 116 | lastGlyph[1] | | (glyphID - firstGlyph) * 4 * sizeof(FT_Short) [byte] 117 +---------------+ | 118 | firstGlyph[1] | | 119 +---------------+ | 120 | offset[1] | | 121 +===============+ | 122 | 123 .... | 124 | 125 48bit value array | 126 +===============+ | 127 | value | <-------+ 128 | | 129 | | 130 | | 131 +---------------+ 132 .... */ 133 134 static GXV_LookupValueDesc gxv_opbd_LookupFmt4_transit(FT_UShort relative_gindex,GXV_LookupValueCPtr base_value_p,FT_Bytes lookuptbl_limit,GXV_Validator gxvalid)135 gxv_opbd_LookupFmt4_transit( FT_UShort relative_gindex, 136 GXV_LookupValueCPtr base_value_p, 137 FT_Bytes lookuptbl_limit, 138 GXV_Validator gxvalid ) 139 { 140 GXV_LookupValueDesc value; 141 142 FT_UNUSED( lookuptbl_limit ); 143 FT_UNUSED( gxvalid ); 144 145 /* XXX: check range? */ 146 value.u = (FT_UShort)( base_value_p->u + 147 relative_gindex * 4 * sizeof ( FT_Short ) ); 148 149 return value; 150 } 151 152 153 /*************************************************************************/ 154 /*************************************************************************/ 155 /***** *****/ 156 /***** opbd TABLE *****/ 157 /***** *****/ 158 /*************************************************************************/ 159 /*************************************************************************/ 160 161 FT_LOCAL_DEF( void ) gxv_opbd_validate(FT_Bytes table,FT_Face face,FT_Validator ftvalid)162 gxv_opbd_validate( FT_Bytes table, 163 FT_Face face, 164 FT_Validator ftvalid ) 165 { 166 GXV_ValidatorRec gxvalidrec; 167 GXV_Validator gxvalid = &gxvalidrec; 168 GXV_opbd_DataRec opbdrec; 169 GXV_opbd_Data opbd = &opbdrec; 170 FT_Bytes p = table; 171 FT_Bytes limit = 0; 172 173 FT_ULong version; 174 175 176 gxvalid->root = ftvalid; 177 gxvalid->table_data = opbd; 178 gxvalid->face = face; 179 180 FT_TRACE3(( "validating `opbd' table\n" )); 181 GXV_INIT; 182 GXV_OPBD_DATA( valueOffset_min ) = 0xFFFFU; 183 184 185 GXV_LIMIT_CHECK( 4 + 2 ); 186 version = FT_NEXT_ULONG( p ); 187 GXV_OPBD_DATA( format ) = FT_NEXT_USHORT( p ); 188 189 190 /* only 0x00010000 is defined (1996) */ 191 GXV_TRACE(( "(version=0x%08x)\n", version )); 192 if ( 0x00010000UL != version ) 193 FT_INVALID_FORMAT; 194 195 /* only values 0 and 1 are defined (1996) */ 196 GXV_TRACE(( "(format=0x%04x)\n", GXV_OPBD_DATA( format ) )); 197 if ( 0x0001 < GXV_OPBD_DATA( format ) ) 198 FT_INVALID_FORMAT; 199 200 gxvalid->lookupval_sign = GXV_LOOKUPVALUE_UNSIGNED; 201 gxvalid->lookupval_func = gxv_opbd_LookupValue_validate; 202 gxvalid->lookupfmt4_trans = gxv_opbd_LookupFmt4_transit; 203 204 gxv_LookupTable_validate( p, limit, gxvalid ); 205 p += gxvalid->subtable_length; 206 207 if ( p > table + GXV_OPBD_DATA( valueOffset_min ) ) 208 { 209 GXV_TRACE(( 210 "found overlap between LookupTable and opbd_value array\n" )); 211 FT_INVALID_OFFSET; 212 } 213 214 FT_TRACE4(( "\n" )); 215 } 216 217 218 /* END */ 219