[sfnt] Speed up handling of invalid format 4 cmaps.
* src/sfnt/ttcmap.c (tt_cmap4_next, tt_cmap4_char_map_binary): Add tests for `num_glyph' from `tt_cmap4_char_map_linear'.
This commit is contained in:
parent
327f2e3e55
commit
acd1879897
@ -1,3 +1,10 @@
|
||||
2016-08-25 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
[sfnt] Speed up handling of invalid format 4 cmaps.
|
||||
|
||||
* src/sfnt/ttcmap.c (tt_cmap4_next, tt_cmap4_char_map_binary): Add
|
||||
tests for `num_glyph' from `tt_cmap4_char_map_linear'.
|
||||
|
||||
2016-08-25 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
* include/freetype/internal/ftdriver.h: Remove unused typedefs.
|
||||
|
@ -763,6 +763,9 @@
|
||||
static void
|
||||
tt_cmap4_next( TT_CMap4 cmap )
|
||||
{
|
||||
TT_Face face = (TT_Face)cmap->cmap.cmap.charmap.face;
|
||||
FT_Byte* limit = face->cmap_table + face->cmap_size;
|
||||
|
||||
FT_UInt charcode;
|
||||
|
||||
|
||||
@ -788,15 +791,19 @@
|
||||
FT_Byte* p = values + 2 * ( charcode - cmap->cur_start );
|
||||
|
||||
|
||||
/* if p > limit, the whole segment is invalid */
|
||||
if ( p > limit )
|
||||
goto Next_Segment;
|
||||
|
||||
do
|
||||
{
|
||||
FT_UInt gindex = FT_NEXT_USHORT( p );
|
||||
|
||||
|
||||
if ( gindex != 0 )
|
||||
if ( gindex )
|
||||
{
|
||||
gindex = (FT_UInt)( (FT_Int)gindex + delta ) & 0xFFFFU;
|
||||
if ( gindex != 0 )
|
||||
if ( gindex )
|
||||
{
|
||||
cmap->cur_charcode = charcode;
|
||||
cmap->cur_gindex = gindex;
|
||||
@ -812,7 +819,26 @@
|
||||
FT_UInt gindex = (FT_UInt)( (FT_Int)charcode + delta ) & 0xFFFFU;
|
||||
|
||||
|
||||
if ( gindex != 0 )
|
||||
if ( gindex >= (FT_UInt)face->root.num_glyphs )
|
||||
{
|
||||
/* we have an invalid glyph index; if there is an overflow, */
|
||||
/* we can adjust `charcode', otherwise the whole segment is */
|
||||
/* invalid */
|
||||
gindex = 0;
|
||||
|
||||
if ( (FT_Int)charcode + delta < 0 &&
|
||||
(FT_Int)end + delta >= 0 )
|
||||
charcode = (FT_UInt)( -delta );
|
||||
|
||||
else if ( (FT_Int)charcode + delta < 0x10000L &&
|
||||
(FT_Int)end + delta >= 0x10000L )
|
||||
charcode = (FT_UInt)( 0x10000L - delta );
|
||||
|
||||
else
|
||||
goto Next_Segment;
|
||||
}
|
||||
|
||||
if ( gindex )
|
||||
{
|
||||
cmap->cur_charcode = charcode;
|
||||
cmap->cur_gindex = gindex;
|
||||
@ -822,6 +848,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
Next_Segment:
|
||||
/* we need to find another range */
|
||||
if ( tt_cmap4_set_range( cmap, cmap->cur_range + 1 ) < 0 )
|
||||
break;
|
||||
@ -1170,6 +1197,9 @@
|
||||
FT_UInt32* pcharcode,
|
||||
FT_Bool next )
|
||||
{
|
||||
TT_Face face = (TT_Face)cmap->cmap.charmap.face;
|
||||
FT_Byte* limit = face->cmap_table + face->cmap_size;
|
||||
|
||||
FT_UInt num_segs2, start, end, offset;
|
||||
FT_Int delta;
|
||||
FT_UInt max, min, mid, num_segs;
|
||||
@ -1221,10 +1251,6 @@
|
||||
if ( mid >= num_segs - 1 &&
|
||||
start == 0xFFFFU && end == 0xFFFFU )
|
||||
{
|
||||
TT_Face face = (TT_Face)cmap->cmap.charmap.face;
|
||||
FT_Byte* limit = face->cmap_table + face->cmap_size;
|
||||
|
||||
|
||||
if ( offset && p + offset + 2 > limit )
|
||||
{
|
||||
delta = 1;
|
||||
@ -1347,13 +1373,43 @@
|
||||
if ( offset )
|
||||
{
|
||||
p += offset + ( charcode - start ) * 2;
|
||||
|
||||
/* if p > limit, the whole segment is invalid */
|
||||
if ( next && p > limit )
|
||||
continue;
|
||||
|
||||
gindex = TT_PEEK_USHORT( p );
|
||||
if ( gindex != 0 )
|
||||
if ( gindex )
|
||||
{
|
||||
gindex = (FT_UInt)( (FT_Int)gindex + delta ) & 0xFFFFU;
|
||||
if ( gindex >= (FT_UInt)face->root.num_glyphs )
|
||||
gindex = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gindex = (FT_UInt)( (FT_Int)charcode + delta ) & 0xFFFFU;
|
||||
|
||||
if ( next && gindex >= (FT_UInt)face->root.num_glyphs )
|
||||
{
|
||||
/* we have an invalid glyph index; if there is an overflow, */
|
||||
/* we can adjust `charcode', otherwise the whole segment is */
|
||||
/* invalid */
|
||||
gindex = 0;
|
||||
|
||||
if ( (FT_Int)charcode + delta < 0 &&
|
||||
(FT_Int)end + delta >= 0 )
|
||||
charcode = (FT_UInt)( -delta );
|
||||
|
||||
else if ( (FT_Int)charcode + delta < 0x10000L &&
|
||||
(FT_Int)end + delta >= 0x10000L )
|
||||
charcode = (FT_UInt)( 0x10000L - delta );
|
||||
|
||||
else
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user