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