freetype-commit
[Top][All Lists]
Advanced

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

[freetype2] master ca4e707: [smooth, raster] Limit bitmap size (#54019).


From: Werner LEMBERG
Subject: [freetype2] master ca4e707: [smooth, raster] Limit bitmap size (#54019).
Date: Wed, 6 Jun 2018 02:19:32 -0400 (EDT)

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

    [smooth, raster] Limit bitmap size (#54019).
    
    * src/raster/ftraster.c [STANDALONE] (FT_Outline_Get_CBox): Add
    function.
    [!STANDALONE]: Include FT_OUTLINE_H.
    (ft_black_render): Compute CBox and reject glyphs larger than
    0xFFFF x 0xFFFF.
    
    * src/smooth/ftgrays.c (gray_raster_render): Reject glyphs larger
    than 0xFFFF x 0xFFFF.
---
 ChangeLog             |  13 ++++++
 src/raster/ftraster.c | 114 +++++++++++++++++++++++++++++++++++++++++++++-----
 src/smooth/ftgrays.c  |   5 +++
 3 files changed, 122 insertions(+), 10 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 4f4e281..048f85a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2018-06-06  Werner Lemberg  <address@hidden>
+
+       [smooth, raster] Limit bitmap size (#54019).
+
+       * src/raster/ftraster.c [STANDALONE] (FT_Outline_Get_CBox): Add
+       function.
+       [!STANDALONE]: Include FT_OUTLINE_H.
+       (ft_black_render): Compute CBox and reject glyphs larger than
+       0xFFFF x 0xFFFF.
+
+       * src/smooth/ftgrays.c (gray_raster_render): Reject glyphs larger
+       than 0xFFFF x 0xFFFF.
+
 2018-06-03  Armin Hasitzka  <address@hidden>
 
        * src/smooth/ftgrays.c (gray_convert_glyph): Remove unused variables.
diff --git a/src/raster/ftraster.c b/src/raster/ftraster.c
index e3da008..cc8fd5f 100644
--- a/src/raster/ftraster.c
+++ b/src/raster/ftraster.c
@@ -65,6 +65,7 @@
 #include <ft2build.h>
 #include "ftraster.h"
 #include FT_INTERNAL_CALC_H   /* for FT_MulDiv and FT_MulDiv_No_Round */
+#include FT_OUTLINE_H         /* for FT_Outline_Get_CBox              */
 
 #endif /* !STANDALONE_ */
 
@@ -2925,6 +2926,94 @@
   }
 
 
+#ifdef STANDALONE_
+
+  /**************************************************************************
+   *
+   * The following functions should only compile in stand-alone mode,
+   * i.e., when building this component without the rest of FreeType.
+   *
+   */
+
+  /**************************************************************************
+   *
+   * @Function:
+   *   FT_Outline_Get_CBox
+   *
+   * @Description:
+   *   Return an outline's `control box'.  The control box encloses all
+   *   the outline's points, including Bézier control points.  Though it
+   *   coincides with the exact bounding box for most glyphs, it can be
+   *   slightly larger in some situations (like when rotating an outline
+   *   that contains Bézier outside arcs).
+   *
+   *   Computing the control box is very fast, while getting the bounding
+   *   box can take much more time as it needs to walk over all segments
+   *   and arcs in the outline.  To get the latter, you can use the
+   *   `ftbbox' component, which is dedicated to this single task.
+   *
+   * @Input:
+   *   outline ::
+   *     A pointer to the source outline descriptor.
+   *
+   * @Output:
+   *   acbox ::
+   *     The outline's control box.
+   *
+   * @Note:
+   *   See @FT_Glyph_Get_CBox for a discussion of tricky fonts.
+   */
+
+  static void
+  FT_Outline_Get_CBox( const FT_Outline*  outline,
+                       FT_BBox           *acbox )
+  {
+    Long  xMin, yMin, xMax, yMax;
+
+
+    if ( outline && acbox )
+    {
+      if ( outline->n_points == 0 )
+      {
+        xMin = 0;
+        yMin = 0;
+        xMax = 0;
+        yMax = 0;
+      }
+      else
+      {
+        FT_Vector*  vec   = outline->points;
+        FT_Vector*  limit = vec + outline->n_points;
+
+
+        xMin = xMax = vec->x;
+        yMin = yMax = vec->y;
+        vec++;
+
+        for ( ; vec < limit; vec++ )
+        {
+          Long  x, y;
+
+
+          x = vec->x;
+          if ( x < xMin ) xMin = x;
+          if ( x > xMax ) xMax = x;
+
+          y = vec->y;
+          if ( y < yMin ) yMin = y;
+          if ( y > yMax ) yMax = y;
+        }
+      }
+      acbox->xMin = xMin;
+      acbox->xMax = xMax;
+      acbox->yMin = yMin;
+      acbox->yMax = yMax;
+    }
+  }
+
+#endif /* STANDALONE_ */
+
+
   /**************************************************************************
    *
    * @Function:
@@ -3183,6 +3272,7 @@
   {
     const FT_Outline*  outline    = (const FT_Outline*)params->source;
     const FT_Bitmap*   target_map = params->target;
+    FT_BBox            cbox;
 
     black_TWorker  worker[1];
 
@@ -3223,19 +3313,23 @@
     if ( !target_map->buffer )
       return FT_THROW( Invalid );
 
+    FT_Outline_Get_CBox( outline, &cbox );
+
     /* reject too large outline coordinates */
-    {
-      FT_Vector*  vec   = outline->points;
-      FT_Vector*  limit = vec + outline->n_points;
+    if ( cbox.xMin < -0x1000000L || cbox.xMax > 0x1000000L ||
+         cbox.yMin < -0x1000000L || cbox.yMax > 0x1000000L )
+      return FT_THROW( Invalid );
 
+    /* truncate the bounding box to integer pixels */
+    cbox.xMin = cbox.xMin >> 6;
+    cbox.yMin = cbox.yMin >> 6;
+    cbox.xMax = ( cbox.xMax + 63 ) >> 6;
+    cbox.yMax = ( cbox.yMax + 63 ) >> 6;
 
-      for ( ; vec < limit; vec++ )
-      {
-        if ( vec->x < -0x1000000L || vec->x > 0x1000000L ||
-             vec->y < -0x1000000L || vec->y > 0x1000000L )
-         return FT_THROW( Invalid );
-      }
-    }
+    /* reject too large glyphs */
+    if ( cbox.xMax - cbox.xMin > 0xFFFF ||
+         cbox.yMax - cbox.yMin > 0xFFFF )
+      return FT_THROW( Invalid );
 
     ras.outline = *outline;
     ras.target  = *target_map;
diff --git a/src/smooth/ftgrays.c b/src/smooth/ftgrays.c
index 10fdddf..1385380 100644
--- a/src/smooth/ftgrays.c
+++ b/src/smooth/ftgrays.c
@@ -1899,6 +1899,11 @@ typedef ptrdiff_t  FT_PtrDist;
     cbox.xMax = ( cbox.xMax + 63 ) >> 6;
     cbox.yMax = ( cbox.yMax + 63 ) >> 6;
 
+    /* reject too large glyphs */
+    if ( cbox.xMax - cbox.xMin > 0xFFFF ||
+         cbox.yMax - cbox.yMin > 0xFFFF )
+      return FT_THROW( Invalid_Outline );
+
     /* compute clipping box */
     if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) )
     {



reply via email to

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