freetype-commit
[Top][All Lists]
Advanced

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

[freetype2] master da34673: [truetype] More sanity tests for GX handling


From: Werner LEMBERG
Subject: [freetype2] master da34673: [truetype] More sanity tests for GX handling.
Date: Sat, 10 Oct 2015 08:21:43 +0000

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

    [truetype] More sanity tests for GX handling.
    
    These tests should mainly help avoid unnecessarily large memory
    allocations in case of malformed fonts.
    
    * src/truetype/ttgxvar.c (ft_var_readpackedpoints,
    ft_var_readpackeddeltas): Check number of points against stream
    size.
    (ft_var_load_avar): Check `pairCount' against table length.
    (ft_var_load_gvar): Check `globalCoordCount' and `glyphCount'
    against table length.
    (tt_face_vary_cvt): Check `tupleCount' and `offsetToData'.
    Fix trace.
    (TT_Vary_Apply_Glyph_Deltas): Fix trace.
    Free `sharedpoints' to avoid memory leak.
---
 ChangeLog              |   18 ++++++++++++
 src/truetype/ttgxvar.c |   69 +++++++++++++++++++++++++++++++++++++++---------
 2 files changed, 74 insertions(+), 13 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 20e8b47..9062221 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,23 @@
 2015-10-10  Werner Lemberg  <address@hidden>
 
+       [truetype] More sanity tests for GX handling.
+
+       These tests should mainly help avoid unnecessarily large memory
+       allocations in case of malformed fonts.
+
+       * src/truetype/ttgxvar.c (ft_var_readpackedpoints,
+       ft_var_readpackeddeltas): Check number of points against stream
+       size.
+       (ft_var_load_avar): Check `pairCount' against table length.
+       (ft_var_load_gvar): Check `globalCoordCount' and `glyphCount'
+       against table length.
+       (tt_face_vary_cvt): Check `tupleCount' and `offsetToData'.
+       Fix trace.
+       (TT_Vary_Apply_Glyph_Deltas): Fix trace.
+       Free `sharedpoints' to avoid memory leak.
+
+2015-10-10  Werner Lemberg  <address@hidden>
+
        [truetype] Better protection against malformed GX data (#46166).
 
        * src/truetype/ttgxvar.c (TT_Vary_Apply_Glyph_Deltas): Correctly
diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c
index e838b87..b8ff141 100644
--- a/src/truetype/ttgxvar.c
+++ b/src/truetype/ttgxvar.c
@@ -149,6 +149,12 @@
       n  |= FT_GET_BYTE();
     }
 
+    if ( n > stream->size - stream->pos )
+    {
+      FT_TRACE1(( "ft_var_readpackedpoints: number of points too large\n" ));
+      return NULL;
+    }
+
     if ( FT_NEW_ARRAY( points, n ) )
       return NULL;
 
@@ -233,6 +239,12 @@
     FT_UNUSED( error );
 
 
+    if ( delta_cnt > stream->size - stream->pos )
+    {
+      FT_TRACE1(( "ft_var_readpackeddeltas: number of points too large\n" ));
+      return NULL;
+    }
+
     if ( FT_NEW_ARRAY( deltas, delta_cnt ) )
       return NULL;
 
@@ -341,7 +353,8 @@
       FT_TRACE5(( "  axis %d:\n", i ));
 
       segment->pairCount = FT_GET_USHORT();
-      if ( FT_NEW_ARRAY( segment->correspondence, segment->pairCount ) )
+      if ( (FT_ULong)segment->pairCount * 4 > table_len                ||
+           FT_NEW_ARRAY( segment->correspondence, segment->pairCount ) )
       {
         /* Failure.  Free everything we have done so far.  We must do */
         /* it right now since loading the `avar' table is optional.   */
@@ -447,10 +460,6 @@
     if ( FT_STREAM_READ_FIELDS( gvar_fields, &gvar_head ) )
       goto Exit;
 
-    blend->tuplecount  = gvar_head.globalCoordCount;
-    blend->gv_glyphcnt = gvar_head.glyphCount;
-    offsetToData       = gvar_start + gvar_head.offsetToData;
-
     if ( gvar_head.version != 0x00010000L )
     {
       FT_TRACE1(( "bad table version\n" ));
@@ -458,8 +467,6 @@
       goto Exit;
     }
 
-    FT_TRACE2(( "loaded\n" ));
-
     if ( gvar_head.axisCount != (FT_UShort)blend->mmvar->num_axis )
     {
       FT_TRACE1(( "ft_var_load_gvar: number of axes in `gvar' and `cvar'\n"
@@ -468,6 +475,27 @@
       goto Exit;
     }
 
+    /* rough sanity check, ignoring offsets */
+    if ( (FT_ULong)gvar_head.globalCoordCount * gvar_head.axisCount >
+           table_len / 2 )
+    {
+      FT_TRACE1(( "ft_var_load_gvar:"
+                  " invalid number of global coordinates\n" ));
+      error = FT_THROW( Invalid_Table );
+      goto Exit;
+    }
+
+    /* rough sanity check: offsets can be either 2 or 4 bytes, */
+    /* and a single variation needs at least 4 bytes per glyph */
+    if ( (FT_ULong)gvar_head.glyphCount *
+           ( ( gvar_head.flags & 1 ) ? 8 : 6 ) > table_len )
+
+    FT_TRACE2(( "loaded\n" ));
+
+    blend->tuplecount  = gvar_head.globalCoordCount;
+    blend->gv_glyphcnt = gvar_head.glyphCount;
+    offsetToData       = gvar_start + gvar_head.offsetToData;
+
     FT_TRACE5(( "gvar: there are %d shared coordinates:\n",
                 blend->tuplecount ));
 
@@ -1353,13 +1381,25 @@
       goto FExit;
 
     tupleCount   = FT_GET_USHORT();
-    offsetToData = table_start + FT_GET_USHORT();
+    offsetToData = FT_GET_USHORT();
+
+    /* rough sanity test */
+    if ( offsetToData + tupleCount * 4 > table_len )
+    {
+      FT_TRACE2(( "tt_face_vary_cvt:"
+                  " invalid CVT variation array header\n" ));
+
+      error = FT_THROW( Invalid_Table );
+      goto FExit;
+    }
+
+    offsetToData += table_start;
 
-    /* The documentation implies there are flags packed into the        */
-    /* tuplecount, but John Jenkins says that shared points don't apply */
-    /* to `cvar', and no other flags are defined.                       */
+    /* The documentation implies there are flags packed into              */
+    /* `tupleCount', but John Jenkins says that shared points don't apply */
+    /* to `cvar', and no other flags are defined.                         */
 
-    FT_TRACE5(( "cvar: there are %d tuples:\n", tupleCount ));
+    FT_TRACE5(( "cvar: there are %d tuples:\n", tupleCount & 0xFFF ));
 
     for ( i = 0; i < ( tupleCount & 0xFFF ); i++ )
     {
@@ -1833,7 +1873,8 @@
       FT_Stream_SeekSet( stream, here );
     }
 
-    FT_TRACE5(( "gvar: there are %d tuples:\n", tupleCount ));
+    FT_TRACE5(( "gvar: there are %d tuples:\n",
+                tupleCount & GX_TC_TUPLE_COUNT_MASK ));
 
     for ( i = 0; i < ( tupleCount & GX_TC_TUPLE_COUNT_MASK ); i++ )
     {
@@ -2013,6 +2054,8 @@
 
       if ( localpoints != ALL_POINTS )
         FT_FREE( localpoints );
+      if ( sharedpoints != ALL_POINTS )
+        FT_FREE( sharedpoints );
       FT_FREE( deltas_x );
       FT_FREE( deltas_y );
 



reply via email to

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