📄 gxvcommn.c
字号:
{ GXV_TRACE(( "too short, glyphs %d - %d are missing\n", i, valid->face->num_glyphs )); if ( valid->root->level >= FT_VALIDATE_PARANOID ) FT_INVALID_GLYPH_ID; break; } value = GXV_LOOKUP_VALUE_LOAD( p, valid->lookupval_sign ); valid->lookupval_func( i, value, valid ); } valid->subtable_length = p - table; GXV_EXIT; } /* ================= Segment Single Format 2 Loolup Table ============== */ /* * Apple spec says: * * To guarantee that a binary search terminates, you must include one or * more special `end of search table' values at the end of the data to * be searched. The number of termination values that need to be * included is table-specific. The value that indicates binary search * termination is 0xFFFF. * * The problem is that nUnits does not include this end-marker. It's * quite difficult to discriminate whether the following 0xFFFF comes from * the end-marker or some next data. * * -- suzuki toshiya <mpsuzuki@hiroshima-u.ac.jp> */ static void gxv_LookupTable_fmt2_skip_endmarkers( FT_Bytes table, FT_UShort unitSize, GXV_Validator valid ) { FT_Bytes p = table; while ( ( p + 4 ) < valid->root->limit ) { if ( p[0] != 0xFF || p[1] != 0xFF || /* lastGlyph */ p[2] != 0xFF || p[3] != 0xFF ) /* firstGlyph */ break; p += unitSize; } valid->subtable_length = p - table; } static void gxv_LookupTable_fmt2_validate( FT_Bytes table, FT_Bytes limit, GXV_Validator valid ) { FT_Bytes p = table; FT_UShort gid; FT_UShort unitSize; FT_UShort nUnits; FT_UShort unit; FT_UShort lastGlyph; FT_UShort firstGlyph; GXV_LookupValueDesc value; GXV_NAME_ENTER( "LookupTable format 2" ); unitSize = nUnits = 0; gxv_BinSrchHeader_validate( p, limit, &unitSize, &nUnits, valid ); p += valid->subtable_length; GXV_UNITSIZE_VALIDATE( "format2", unitSize, nUnits, 6 ); for ( unit = 0, gid = 0; unit < nUnits; unit++ ) { GXV_LIMIT_CHECK( 2 + 2 + 2 ); lastGlyph = FT_NEXT_USHORT( p ); firstGlyph = FT_NEXT_USHORT( p ); value = GXV_LOOKUP_VALUE_LOAD( p, valid->lookupval_sign ); gxv_glyphid_validate( firstGlyph, valid ); gxv_glyphid_validate( lastGlyph, valid ); if ( lastGlyph < gid ) { GXV_TRACE(( "reverse ordered segment specification:" " lastGlyph[%d]=%d < lastGlyph[%d]=%d\n", unit, lastGlyph, unit - 1 , gid )); if ( valid->root->level >= FT_VALIDATE_PARANOID ) FT_INVALID_GLYPH_ID; } if ( lastGlyph < firstGlyph ) { GXV_TRACE(( "reverse ordered range specification at unit %d:", " lastGlyph %d < firstGlyph %d ", unit, lastGlyph, firstGlyph )); if ( valid->root->level >= FT_VALIDATE_PARANOID ) FT_INVALID_GLYPH_ID; if ( valid->root->level == FT_VALIDATE_TIGHT ) continue; /* ftxvalidator silently skips such an entry */ FT_TRACE4(( "continuing with exchanged values\n" )); gid = firstGlyph; firstGlyph = lastGlyph; lastGlyph = gid; } for ( gid = firstGlyph; gid <= lastGlyph; gid++ ) valid->lookupval_func( gid, value, valid ); } gxv_LookupTable_fmt2_skip_endmarkers( p, unitSize, valid ); p += valid->subtable_length; valid->subtable_length = p - table; GXV_EXIT; } /* ================= Segment Array Format 4 Lookup Table =============== */ static void gxv_LookupTable_fmt4_validate( FT_Bytes table, FT_Bytes limit, GXV_Validator valid ) { FT_Bytes p = table; FT_UShort unit; FT_UShort gid; FT_UShort unitSize; FT_UShort nUnits; FT_UShort lastGlyph; FT_UShort firstGlyph; GXV_LookupValueDesc base_value; GXV_LookupValueDesc value; GXV_NAME_ENTER( "LookupTable format 4" ); unitSize = nUnits = 0; gxv_BinSrchHeader_validate( p, limit, &unitSize, &nUnits, valid ); p += valid->subtable_length; GXV_UNITSIZE_VALIDATE( "format4", unitSize, nUnits, 6 ); for ( unit = 0, gid = 0; unit < nUnits; unit++ ) { GXV_LIMIT_CHECK( 2 + 2 ); lastGlyph = FT_NEXT_USHORT( p ); firstGlyph = FT_NEXT_USHORT( p ); gxv_glyphid_validate( firstGlyph, valid ); gxv_glyphid_validate( lastGlyph, valid ); if ( lastGlyph < gid ) { GXV_TRACE(( "reverse ordered segment specification:" " lastGlyph[%d]=%d < lastGlyph[%d]=%d\n", unit, lastGlyph, unit - 1 , gid )); if ( valid->root->level >= FT_VALIDATE_PARANOID ) FT_INVALID_GLYPH_ID; } if ( lastGlyph < firstGlyph ) { GXV_TRACE(( "reverse ordered range specification at unit %d:", " lastGlyph %d < firstGlyph %d ", unit, lastGlyph, firstGlyph )); if ( valid->root->level >= FT_VALIDATE_PARANOID ) FT_INVALID_GLYPH_ID; if ( valid->root->level == FT_VALIDATE_TIGHT ) continue; /* ftxvalidator silently skips such an entry */ FT_TRACE4(( "continuing with exchanged values\n" )); gid = firstGlyph; firstGlyph = lastGlyph; lastGlyph = gid; } GXV_LIMIT_CHECK( 2 ); base_value = GXV_LOOKUP_VALUE_LOAD( p, GXV_LOOKUPVALUE_UNSIGNED ); for ( gid = firstGlyph; gid <= lastGlyph; gid++ ) { value = valid->lookupfmt4_trans( (FT_UShort)( gid - firstGlyph ), base_value, limit, valid ); valid->lookupval_func( gid, value, valid ); } } gxv_LookupTable_fmt2_skip_endmarkers( p, unitSize, valid ); p += valid->subtable_length; valid->subtable_length = p - table; GXV_EXIT; } /* ================= Segment Table Format 6 Lookup Table =============== */ static void gxv_LookupTable_fmt6_skip_endmarkers( FT_Bytes table, FT_UShort unitSize, GXV_Validator valid ) { FT_Bytes p = table; while ( p < valid->root->limit ) { if ( p[0] != 0xFF || p[1] != 0xFF ) break; p += unitSize; } valid->subtable_length = p - table; } static void gxv_LookupTable_fmt6_validate( FT_Bytes table, FT_Bytes limit, GXV_Validator valid ) { FT_Bytes p = table; FT_UShort unit; FT_UShort prev_glyph; FT_UShort unitSize; FT_UShort nUnits; FT_UShort glyph; GXV_LookupValueDesc value; GXV_NAME_ENTER( "LookupTable format 6" ); unitSize = nUnits = 0; gxv_BinSrchHeader_validate( p, limit, &unitSize, &nUnits, valid ); p += valid->subtable_length; GXV_UNITSIZE_VALIDATE( "format6", unitSize, nUnits, 4 ); for ( unit = 0, prev_glyph = 0; unit < nUnits; unit++ ) { GXV_LIMIT_CHECK( 2 + 2 ); glyph = FT_NEXT_USHORT( p ); value = GXV_LOOKUP_VALUE_LOAD( p, valid->lookupval_sign ); if ( gxv_glyphid_validate( glyph, valid ) ) GXV_TRACE(( " endmarker found within defined range" " (entry %d < nUnits=%d)\n", unit, nUnits )); if ( prev_glyph > glyph ) { GXV_TRACE(( "current gid 0x%04x < previous gid 0x%04x\n", glyph, prev_glyph )); if ( valid->root->level >= FT_VALIDATE_PARANOID ) FT_INVALID_GLYPH_ID; } prev_glyph = glyph; valid->lookupval_func( glyph, value, valid ); } gxv_LookupTable_fmt6_skip_endmarkers( p, unitSize, valid ); p += valid->subtable_length; valid->subtable_length = p - table; GXV_EXIT; } /* ================= Trimmed Array Format 8 Lookup Table =============== */ static void gxv_LookupTable_fmt8_validate( FT_Bytes table, FT_Bytes limit, GXV_Validator valid ) { FT_Bytes p = table; FT_UShort i; GXV_LookupValueDesc value; FT_UShort firstGlyph; FT_UShort glyphCount; GXV_NAME_ENTER( "LookupTable format 8" ); /* firstGlyph + glyphCount */ GXV_LIMIT_CHECK( 2 + 2 ); firstGlyph = FT_NEXT_USHORT( p ); glyphCount = FT_NEXT_USHORT( p ); gxv_glyphid_validate( firstGlyph, valid ); gxv_glyphid_validate( (FT_UShort)( firstGlyph + glyphCount ), valid ); /* valueArray */ for ( i = 0; i < glyphCount; i++ ) { GXV_LIMIT_CHECK( 2 ); value = GXV_LOOKUP_VALUE_LOAD( p, valid->lookupval_sign ); valid->lookupval_func( (FT_UShort)( firstGlyph + i ), value, valid ); } valid->subtable_length = p - table; GXV_EXIT; } FT_LOCAL_DEF( void ) gxv_LookupTable_validate( FT_Bytes table, FT_Bytes limit, GXV_Validator valid ) { FT_Bytes p = table; FT_UShort format; GXV_Validate_Func fmt_funcs_table[] = { gxv_LookupTable_fmt0_validate, /* 0 */ NULL, /* 1 */ gxv_LookupTable_fmt2_validate, /* 2 */ NULL, /* 3 */ gxv_LookupTable_fmt4_validate, /* 4 */ NULL, /* 5 */ gxv_LookupTable_fmt6_validate, /* 6 */ NULL, /* 7 */ gxv_LookupTable_fmt8_validate, /* 8 */ }; GXV_Validate_Func func; GXV_NAME_ENTER( "LookupTable" ); /* lookuptbl_head may be used in fmt4 transit function. */ valid->lookuptbl_head = table; /* format */ GXV_LIMIT_CHECK( 2 ); format = FT_NEXT_USHORT( p ); GXV_TRACE(( " (format %d)\n", format )); if ( format > 8 ) FT_INVALID_FORMAT; func = fmt_funcs_table[format]; if ( func == NULL ) FT_INVALID_FORMAT; func( p, limit, valid ); p += valid->subtable_length; valid->subtable_length = p - table; GXV_EXIT; } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** Glyph ID *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ FT_LOCAL_DEF( FT_Int ) gxv_glyphid_validate( FT_UShort gid, GXV_Validator valid ) { FT_Face face; if ( gid == 0xFFFFU ) { GXV_EXIT; return 1; } face = valid->face; if ( face->num_glyphs < gid ) { GXV_TRACE(( " gxv_glyphid_check() gid overflow: num_glyphs %d < %d\n", face->num_glyphs, gid )); if ( valid->root->level >= FT_VALIDATE_PARANOID ) FT_INVALID_GLYPH_ID; } return 0; } /*************************************************************************/ /*************************************************************************/ /***** *****/ /***** CONTROL POINT *****/ /***** *****/ /*************************************************************************/ /*************************************************************************/ FT_LOCAL_DEF( void ) gxv_ctlPoint_validate( FT_UShort gid, FT_Short ctl_point, GXV_Validator valid ) { FT_Face face; FT_Error error; FT_GlyphSlot glyph; FT_Outline outline; short n_points; face = valid->face; error = FT_Load_Glyph( face, gid, FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_TRANSFORM ); if ( error ) FT_INVALID_GLYPH_ID; glyph = face->glyph; outline = glyph->outline; n_points = outline.n_points; if ( !( ctl_point < n_points ) ) FT_INVALID_DATA; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -