[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:
Werner Lemberg 2016-08-25 17:12:46 +02:00
parent 327f2e3e55
commit acd1879897
2 changed files with 71 additions and 8 deletions

View File

@ -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.

View File

@ -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;
}
}