📄 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 + -