Commit 53c5e4bd87ff8035d91022204bb5f3a051e78a99

Werner Lemberg 2018-09-12T07:27:30

* src/truetype/ttgxvar.c (ft_var_load_gvar): Check `glyphoffsets'.

diff --git a/ChangeLog b/ChangeLog
index 5f2fb97..ac063f1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2018-09-12  Werner Lemberg  <wl@gnu.org>
+
+	* src/truetype/ttgxvar.c (ft_var_load_gvar): Check `glyphoffsets'.
+
 2018-09-10  Armin Hasitzka  <prince.cherusker@gmail.com>
 
 	* src/pshinter/pshrec.c (t2_hints_stems): Mask numeric overflow.
diff --git a/src/truetype/ttgxvar.c b/src/truetype/ttgxvar.c
index fef0c8a..3a2c540 100644
--- a/src/truetype/ttgxvar.c
+++ b/src/truetype/ttgxvar.c
@@ -1531,24 +1531,51 @@
 
     if ( gvar_head.flags & 1 )
     {
+      FT_ULong  limit = gvar_start + table_len;
+
+
       /* long offsets (one more offset than glyphs, to mark size of last) */
       if ( FT_FRAME_ENTER( ( blend->gv_glyphcnt + 1 ) * 4L ) )
         goto Exit;
 
       for ( i = 0; i <= blend->gv_glyphcnt; i++ )
+      {
         blend->glyphoffsets[i] = offsetToData + FT_GET_ULONG();
+        /* use `>', not `>=' */
+        if ( blend->glyphoffsets[i] > limit )
+        {
+          FT_TRACE2(( "ft_var_load_gvar:"
+                      " invalid glyph variation data offset for index %d\n",
+                      i ));
+          error = FT_THROW( Invalid_Table );
+          goto Exit;
+        }
+      }
 
       FT_FRAME_EXIT();
     }
     else
     {
+      FT_ULong  limit = gvar_start + table_len;
+
+
       /* short offsets (one more offset than glyphs, to mark size of last) */
       if ( FT_FRAME_ENTER( ( blend->gv_glyphcnt + 1 ) * 2L ) )
         goto Exit;
 
       for ( i = 0; i <= blend->gv_glyphcnt; i++ )
+      {
         blend->glyphoffsets[i] = offsetToData + FT_GET_USHORT() * 2;
-                                               /* XXX: Undocumented: `*2'! */
+        /* use `>', not `>=' */
+        if ( blend->glyphoffsets[i] > limit )
+        {
+          FT_TRACE2(( "ft_var_load_gvar:"
+                      " invalid glyph variation data offset for index %d\n",
+                      i ));
+          error = FT_THROW( Invalid_Table );
+          goto Exit;
+        }
+      }
 
       FT_FRAME_EXIT();
     }