From 758d55e522eb426dad2f15adc1d945f7896d7b29 Mon Sep 17 00:00:00 2001 From: Werner Lemberg Date: Wed, 4 Nov 2015 11:44:47 +0100 Subject: [PATCH] [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'. --- ChangeLog | 14 ++++++++++ include/freetype/internal/tttypes.h | 3 +++ src/truetype/ttgload.c | 40 +++++++++++++++++++++++++++-- 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 8c39fbfa4..558a6697f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +2015-11-04 Werner Lemberg + + [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 [truetype] Better tracing of composite glyphs. diff --git a/include/freetype/internal/tttypes.h b/include/freetype/internal/tttypes.h index 1507a7c57..000c5a859 100644 --- a/include/freetype/internal/tttypes.h +++ b/include/freetype/internal/tttypes.h @@ -1515,6 +1515,9 @@ FT_BEGIN_HEADER FT_Byte* cursor; FT_Byte* limit; + /* since version 2.6.2 */ + FT_ListRec composites; + } TT_LoaderRec; diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c index 93647de93..9a8b458db 100644 --- a/src/truetype/ttgload.c +++ b/src/truetype/ttgload.c @@ -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 ); + } + + /*************************************************************************/ /* */ /* */ @@ -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. */