ref: ca4e707aa10782a0123011a54bd8c0d7da837b39
parent: 78d85b9c84f404025e287449695dc3e26d8c276c
author: Werner Lemberg <[email protected]>
date: Wed Jun 6 04:18:23 EDT 2018
[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.
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2018-06-06 Werner Lemberg <[email protected]>
+
+ [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 <[email protected]>
* src/smooth/ftgrays.c (gray_convert_glyph): Remove unused variables.
--- 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,9 +2926,97 @@
}
+#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:
* Render_Single_Pass
*
* @Description:
@@ -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;
--- a/src/smooth/ftgrays.c
+++ b/src/smooth/ftgrays.c
@@ -1899,6 +1899,11 @@
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 ) )
{