[truetype] Catch infinite recursion in subglyphs (#46372).

* include/freetype/internal/tttypes.h (TT_LoaderRec): New field
`composites'.

* src/truetype/ttgload.c: Include FT_LIST_H.
(load_truetype_glyph): Add composite subglyph index to a list;
abort if index is already in list.
(tt_loader_init): Updated.
(tt_loader_done): New function.
(TT_Load_Glyph): Call `tt_loader_done'.
This commit is contained in:
Werner Lemberg 2015-11-04 11:44:47 +01:00
parent 040edaf5fb
commit 758d55e522
3 changed files with 55 additions and 2 deletions

View File

@ -1,3 +1,17 @@
2015-11-04 Werner Lemberg <wl@gnu.org>
[truetype] Catch infinite recursion in subglyphs (#46372).
* include/freetype/internal/tttypes.h (TT_LoaderRec): New field
`composites'.
* src/truetype/ttgload.c: Include FT_LIST_H.
(load_truetype_glyph): Add composite subglyph index to a list;
abort if index is already in list.
(tt_loader_init): Updated.
(tt_loader_done): New function.
(TT_Load_Glyph): Call `tt_loader_done'.
2015-11-04 Werner Lemberg <wl@gnu.org>
[truetype] Better tracing of composite glyphs.

View File

@ -1515,6 +1515,9 @@ FT_BEGIN_HEADER
FT_Byte* cursor;
FT_Byte* limit;
/* since version 2.6.2 */
FT_ListRec composites;
} TT_LoaderRec;

View File

@ -24,6 +24,7 @@
#include FT_TRUETYPE_TAGS_H
#include FT_OUTLINE_H
#include FT_TRUETYPE_DRIVER_H
#include FT_LIST_H
#include "ttgload.h"
#include "ttpload.h"
@ -1633,11 +1634,32 @@
/* otherwise, load a composite! */
else if ( loader->n_contours == -1 )
{
FT_Memory memory = face->root.memory;
FT_UInt start_point;
FT_UInt start_contour;
FT_ULong ins_pos; /* position of composite instructions, if any */
/* check whether we already have a composite glyph with this index */
if ( FT_List_Find( &loader->composites, (void*)glyph_index ) )
{
FT_TRACE1(( "TT_Load_Composite_Glyph:"
" infinite recursion detected\n" ));
error = FT_THROW( Invalid_Composite );
goto Exit;
}
else
{
FT_ListNode node;
if ( FT_NEW( node ) )
goto Exit;
node->data = (void*)glyph_index;
FT_List_Add( &loader->composites, node );
}
start_point = (FT_UInt)gloader->base.outline.n_points;
start_contour = (FT_UInt)gloader->base.outline.n_contours;
@ -1665,8 +1687,6 @@
char* tags = NULL;
short* contours = NULL;
FT_Memory memory = face->root.memory;
limit = (short)gloader->current.num_subglyphs;
@ -2399,10 +2419,23 @@
loader->glyph = (FT_GlyphSlot)glyph;
loader->stream = stream;
loader->composites.head = NULL;
loader->composites.tail = NULL;
return FT_Err_Ok;
}
static void
tt_loader_done( TT_Loader loader )
{
FT_List_Finalize( &loader->composites,
NULL,
loader->face->root.memory,
NULL );
}
/*************************************************************************/
/* */
/* <Function> */
@ -2459,6 +2492,7 @@
/* for the bbox we need the header only */
(void)tt_loader_init( &loader, size, glyph, load_flags, TRUE );
(void)load_truetype_glyph( &loader, glyph_index, 0, TRUE );
tt_loader_done( &loader );
glyph->linearHoriAdvance = loader.linear;
glyph->linearVertAdvance = loader.vadvance;
@ -2554,6 +2588,8 @@
error = compute_glyph_metrics( &loader, glyph_index );
}
tt_loader_done( &loader );
/* Set the `high precision' bit flag. */
/* This is _critical_ to get correct output for monochrome */
/* TrueType glyphs at all sizes using the bytecode interpreter. */