freetype-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[freetype2] master 6e339b8 1/2: [truetype] Avoid nested frames.


From: Werner LEMBERG
Subject: [freetype2] master 6e339b8 1/2: [truetype] Avoid nested frames.
Date: Sun, 26 Aug 2018 06:04:01 -0400 (EDT)

branch: master
commit 6e339b8d8e5641f0f2d5240f992336393a983107
Author: Werner Lemberg <address@hidden>
Commit: Werner Lemberg <address@hidden>

    [truetype] Avoid nested frames.
    
    Triggered by
    
      https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10054
    
    * src/truetype/ttgload.c (load_truetype_glyph): Don't use variable
    `opened_frame' to trace whether a frame must be closed at the end of
    function: This fails because `TT_Vary_Apply_Glyph_Deltas' (which
    gets called for space glyphs) uses a frame by itself.  Instead,
    close the frame after loading the header, then use another frame for
    the remaining part of the glyph later on.
    
    Also avoid calling `tt_get_metrics' twice under some circumstances.
---
 ChangeLog              | 17 ++++++++++++++
 src/truetype/ttgload.c | 62 ++++++++++++++++++++++++--------------------------
 2 files changed, 47 insertions(+), 32 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 0aa2a2b..80a4855 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,22 @@
 2018-08-26  Werner Lemberg  <address@hidden>
 
+       [truetype] Avoid nested frames.
+
+       Triggered by
+
+         https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10054
+
+       * src/truetype/ttgload.c (load_truetype_glyph): Don't use variable
+       `opened_frame' to trace whether a frame must be closed at the end of
+       function: This fails because `TT_Vary_Apply_Glyph_Deltas' (which
+       gets called for space glyphs) uses a frame by itself.  Instead,
+       close the frame after loading the header, then use another frame for
+       the remaining part of the glyph later on.
+
+       Also avoid calling `tt_get_metrics' twice under some circumstances.
+
+2018-08-26  Werner Lemberg  <address@hidden>
+
        Various minor clean-ups.
 
        * src/base/ftapi.c: Remove.  Unused.
diff --git a/src/truetype/ttgload.c b/src/truetype/ttgload.c
index d767584..b59e978 100644
--- a/src/truetype/ttgload.c
+++ b/src/truetype/ttgload.c
@@ -1534,12 +1534,11 @@
                        FT_UInt    recurse_count,
                        FT_Bool    header_only )
   {
-    FT_Error        error        = FT_Err_Ok;
+    FT_Error        error   = FT_Err_Ok;
     FT_Fixed        x_scale, y_scale;
     FT_ULong        offset;
-    TT_Face         face         = loader->face;
-    FT_GlyphLoader  gloader      = loader->gloader;
-    FT_Bool         opened_frame = 0;
+    TT_Face         face    = loader->face;
+    FT_GlyphLoader  gloader = loader->gloader;
 
 #ifdef FT_CONFIG_OPTION_INCREMENTAL
     FT_StreamRec    inc_stream;
@@ -1572,15 +1571,15 @@
 
     loader->glyph_index = glyph_index;
 
-    if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
+    if ( loader->load_flags & FT_LOAD_NO_SCALE )
     {
-      x_scale = loader->size->metrics->x_scale;
-      y_scale = loader->size->metrics->y_scale;
+      x_scale = 0x10000L;
+      y_scale = 0x10000L;
     }
     else
     {
-      x_scale = 0x10000L;
-      y_scale = 0x10000L;
+      x_scale = loader->size->metrics->x_scale;
+      y_scale = loader->size->metrics->y_scale;
     }
 
     /* Set `offset' to the start of the glyph relative to the start of */
@@ -1639,38 +1638,36 @@
       if ( error )
         goto Exit;
 
-      opened_frame = 1;
-
       /* read glyph header first */
       error = face->read_glyph_header( loader );
-      if ( error )
-        goto Exit;
 
-      /* the metrics must be computed after loading the glyph header */
-      /* since we need the glyph's `yMax' value in case the vertical */
-      /* metrics must be emulated                                    */
-      error = tt_get_metrics( loader, glyph_index );
-      if ( error )
-        goto Exit;
+      face->forget_glyph_frame( loader );
 
-      if ( header_only )
+      if ( error )
         goto Exit;
     }
 
+    /* a space glyph */
     if ( loader->byte_len == 0 || loader->n_contours == 0 )
     {
       loader->bbox.xMin = 0;
       loader->bbox.xMax = 0;
       loader->bbox.yMin = 0;
       loader->bbox.yMax = 0;
+    }
 
-      error = tt_get_metrics( loader, glyph_index );
-      if ( error )
-        goto Exit;
+    /* the metrics must be computed after loading the glyph header */
+    /* since we need the glyph's `yMax' value in case the vertical */
+    /* metrics must be emulated                                    */
+    error = tt_get_metrics( loader, glyph_index );
+    if ( error )
+      goto Exit;
 
-      if ( header_only )
-        goto Exit;
+    if ( header_only )
+      goto Exit;
 
+    if ( loader->byte_len == 0 || loader->n_contours == 0 )
+    {
       /* must initialize points before (possibly) overriding */
       /* glyph metrics from the incremental interface        */
       tt_loader_set_pp( loader );
@@ -1726,7 +1723,6 @@
         loader->pp4.x = points[3].x;
         loader->pp4.y = points[3].y;
 
-
         /* recalculate linear horizontal and vertical advances */
         /* if we don't have HVAR and VVAR, respectively        */
         if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
@@ -1767,6 +1763,14 @@
     /***********************************************************************/
     /***********************************************************************/
 
+    /* we now open a frame again, right after the glyph header */
+    /* (which consists of 10 bytes)                            */
+    error = face->access_glyph_frame( loader, glyph_index,
+                                      face->glyf_offset + offset + 10,
+                                      (FT_UInt)loader->byte_len - 10 );
+    if ( error )
+      goto Exit;
+
     /* if it is a simple glyph, load it */
 
     if ( loader->n_contours > 0 )
@@ -1777,7 +1781,6 @@
 
       /* all data have been read */
       face->forget_glyph_frame( loader );
-      opened_frame = 0;
 
       error = TT_Process_Simple_Glyph( loader );
       if ( error )
@@ -1812,7 +1815,6 @@
        * pointers with a width of at least 32 bits.
        */
 
-
       /* clear the nodes filled by sibling chains */
       node = ft_list_get_node_at( &loader->composites, recurse_count );
       for ( node2 = node; node2; node2 = node2->next )
@@ -1852,7 +1854,6 @@
 
       /* all data we need are read */
       face->forget_glyph_frame( loader );
-      opened_frame = 0;
 
 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
 
@@ -2107,9 +2108,6 @@
 
   Exit:
 
-    if ( opened_frame )
-      face->forget_glyph_frame( loader );
-
 #ifdef FT_CONFIG_OPTION_INCREMENTAL
 
     if ( glyph_data_loaded )



reply via email to

[Prev in Thread] Current Thread [Next in Thread]