shithub: freetype+ttf2subf

Download patch

ref: 758d55e522eb426dad2f15adc1d945f7896d7b29
parent: 040edaf5fb6eea9d6b784a187e9880a8e6348fff
author: Werner Lemberg <[email protected]>
date: Wed Nov 4 06:44:47 EST 2015

[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'.

git/fs: mount .git/fs: mount/attach disallowed
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,19 @@
 2015-11-04  Werner Lemberg  <[email protected]>
 
+	[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  <[email protected]>
+
 	[truetype] Better tracing of composite glyphs.
 
 	* src/truetype/ttgload.c (TT_Load_Composite_Glyph,
--- a/include/freetype/internal/tttypes.h
+++ b/include/freetype/internal/tttypes.h
@@ -1515,6 +1515,9 @@
     FT_Byte*         cursor;
     FT_Byte*         limit;
 
+    /* since version 2.6.2 */
+    FT_ListRec       composites;
+
   } TT_LoaderRec;
 
 
--- 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,9 +1687,7 @@
         char*       tags     = NULL;
         short*      contours = NULL;
 
-        FT_Memory  memory = face->root.memory;
 
-
         limit = (short)gloader->current.num_subglyphs;
 
         /* construct an outline structure for              */
@@ -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;
 
@@ -2553,6 +2587,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      */