diff --git a/ChangeLog b/ChangeLog index 6a4ca57c5..9c0b0124f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2018-08-09 Alexei Podtelezhnikov + + [raster, smooth] Reinstate bitmap size limits. + + This again moves outline and bitmap size checks one level up. + + * src/base/ftoutln.c (FT_Outline_Render): Explicitly reject enormous + outlines. + * src/raster/ftrend1.c (ft_raster1_render): Reject enormous bitmaps + and, therefore, outlines that require them. + * src/smooth/ftsmooth.c (ft_smooth_render_generic): Ditto. + + * src/raster/ftraster.c (ft_black_render): Remove outline size checks. + * src/smooth/ftgrays.c (gray_raster_render): Ditto. + [STANDALONE]: Remove `FT_Outline_Get_CBox' copy. + 2018-08-08 Alexei Podtelezhnikov [pcf] Revert massive unsigning. diff --git a/src/base/ftoutln.c b/src/base/ftoutln.c index 09a6a1ffc..611b4f60f 100644 --- a/src/base/ftoutln.c +++ b/src/base/ftoutln.c @@ -619,6 +619,7 @@ FT_Error error; FT_Renderer renderer; FT_ListNode node; + FT_BBox cbox; if ( !library ) @@ -630,6 +631,11 @@ if ( !params ) return FT_THROW( Invalid_Argument ); + FT_Outline_Get_CBox( outline, &cbox ); + if ( cbox.xMin < -0x1000000L || cbox.yMin < -0x1000000L || + cbox.xMax > 0x1000000L || cbox.yMax > 0x1000000L ) + return FT_THROW( Invalid_Outline ); + renderer = library->cur_renderer; node = library->renderers.head; diff --git a/src/raster/ftraster.c b/src/raster/ftraster.c index eece0f848..8a583ea5d 100644 --- a/src/raster/ftraster.c +++ b/src/raster/ftraster.c @@ -3251,7 +3251,6 @@ { const FT_Outline* outline = (const FT_Outline*)params->source; const FT_Bitmap* target_map = params->target; - FT_BBox cbox; black_TWorker worker[1]; @@ -3292,24 +3291,6 @@ if ( !target_map->buffer ) return FT_THROW( Invalid ); - FT_Outline_Get_CBox( outline, &cbox ); - - /* reject too large outline coordinates */ - 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; - - /* 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/raster/ftrend1.c b/src/raster/ftrend1.c index 205cd9b31..e8ea9cbe1 100644 --- a/src/raster/ftrend1.c +++ b/src/raster/ftrend1.c @@ -129,6 +129,14 @@ ft_glyphslot_preset_bitmap( slot, mode, origin ); + if ( bitmap->width > 0x7FFF || bitmap->rows > 0x7FFF ) + { + FT_ERROR(( "ft_raster1_render: glyph is too large: %u x %u\n", + bitmap->width, bitmap->rows )); + error = FT_THROW( Raster_Overflow ); + goto Exit; + } + /* allocate new one */ if ( FT_ALLOC_MULT( bitmap->buffer, bitmap->rows, bitmap->pitch ) ) goto Exit; diff --git a/src/smooth/ftgrays.c b/src/smooth/ftgrays.c index b6598aa0e..8f2a600ad 100644 --- a/src/smooth/ftgrays.c +++ b/src/smooth/ftgrays.c @@ -1611,83 +1611,6 @@ typedef ptrdiff_t FT_PtrDist; return FT_THROW( Invalid_Outline ); } - - /************************************************************************** - * - * @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 ) - { - TPos 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++ ) - { - TPos 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_ */ @@ -1832,7 +1755,7 @@ typedef ptrdiff_t FT_PtrDist; { const FT_Outline* outline = (const FT_Outline*)params->source; const FT_Bitmap* target_map = params->target; - FT_BBox cbox, clip; + FT_BBox clip; #ifndef FT_STATIC_RASTER gray_TWorker worker[1]; @@ -1895,26 +1818,11 @@ typedef ptrdiff_t FT_PtrDist; ras.render_span_data = NULL; } - FT_Outline_Get_CBox( outline, &cbox ); - - /* reject too large outline coordinates */ - if ( cbox.xMin < -0x1000000L || cbox.xMax > 0x1000000L || - cbox.yMin < -0x1000000L || cbox.yMax > 0x1000000L ) - return FT_THROW( Invalid_Outline ); - - /* 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; - - /* 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 ) ) + if ( params->flags & FT_RASTER_FLAG_DIRECT && + params->flags & FT_RASTER_FLAG_CLIP ) + clip = params->clip_box; + else { /* compute clip box from target pixmap */ clip.xMin = 0; @@ -1922,21 +1830,12 @@ typedef ptrdiff_t FT_PtrDist; clip.xMax = (FT_Pos)target_map->width; clip.yMax = (FT_Pos)target_map->rows; } - else if ( params->flags & FT_RASTER_FLAG_CLIP ) - clip = params->clip_box; - else - { - clip.xMin = -32768L; - clip.yMin = -32768L; - clip.xMax = 32767L; - clip.yMax = 32767L; - } /* clip to target bitmap, exit if nothing to do */ - ras.min_ex = FT_MAX( cbox.xMin, clip.xMin ); - ras.min_ey = FT_MAX( cbox.yMin, clip.yMin ); - ras.max_ex = FT_MIN( cbox.xMax, clip.xMax ); - ras.max_ey = FT_MIN( cbox.yMax, clip.yMax ); + ras.min_ex = clip.xMin; + ras.min_ey = clip.yMin; + ras.max_ex = clip.xMax; + ras.max_ey = clip.yMax; if ( ras.max_ex <= ras.min_ex || ras.max_ey <= ras.min_ey ) return 0; diff --git a/src/smooth/ftsmooth.c b/src/smooth/ftsmooth.c index 1007f39a6..c6b7e21d4 100644 --- a/src/smooth/ftsmooth.c +++ b/src/smooth/ftsmooth.c @@ -147,6 +147,14 @@ ft_glyphslot_preset_bitmap( slot, mode, origin ); + if ( bitmap->width > 0x7FFF || bitmap->rows > 0x7FFF ) + { + FT_ERROR(( "ft_smooth_render_generic: glyph is too large: %u x %u\n", + bitmap->width, bitmap->rows )); + error = FT_THROW( Raster_Overflow ); + goto Exit; + } + /* allocate new one */ if ( FT_ALLOC_MULT( bitmap->buffer, bitmap->rows, bitmap->pitch ) ) goto Exit;