From ebcc96e559257756478bb93304fbd973857c4c90 Mon Sep 17 00:00:00 2001 From: Anuj Verma Date: Mon, 2 Aug 2021 08:40:43 +0530 Subject: [PATCH] Fix invalid memory access in `bsdf` rasterizer. Do not generate SDF from bitmap if the `FT_GLYPH_OWN_BITMAP` flag is not set. In some cases the bitmap buffer is freed but still points to a valid address; to handle those cases check the flag before accessing the memory. * src/sdf/ftsdfrend.c (ft_bsdf_render): Handle the above case. Also, return an error message if the bitmap's rows/pitch is invalid, otherwise `slot->buffer` might be assigned to some invalid memory location. (ft_sdf_render): Same as above. Plus, move the outline back to original state after rasterization and not if any error occurs. Signed-off-by: Anuj Verma --- src/sdf/ftsdfrend.c | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/src/sdf/ftsdfrend.c b/src/sdf/ftsdfrend.c index 420ad496c..30f2e62a4 100644 --- a/src/sdf/ftsdfrend.c +++ b/src/sdf/ftsdfrend.c @@ -298,8 +298,15 @@ goto Exit; } + /* the rows and pitch must be valid after presetting the */ + /* bitmap using outline */ if ( !bitmap->rows || !bitmap->pitch ) + { + FT_ERROR(( "ft_sdf_render: failed to preset bitmap\n" )); + + error = FT_THROW( Cannot_Render_Glyph ); goto Exit; + } /* the padding will simply be equal to the `spread' */ x_pad = sdf_module->spread; @@ -350,6 +357,10 @@ error = render->raster_render( render->raster, (const FT_Raster_Params*)¶ms ); + /* transform the outline back to the original state */ + if ( x_shift || y_shift ) + FT_Outline_Translate( outline, -x_shift, -y_shift ); + Exit: if ( !error ) { @@ -362,9 +373,6 @@ slot->internal->flags &= ~FT_GLYPH_OWN_BITMAP; } - if ( x_shift || y_shift ) - FT_Outline_Translate( outline, -x_shift, -y_shift ); - return error; } @@ -506,8 +514,24 @@ goto Exit; } - if ( !bitmap->rows || !bitmap->pitch ) + /* Do not generate SDF if the bitmap is not owned by the */ + /* glyph: it might be that the source buffer is already freed. */ + if ( !( slot->internal->flags & FT_GLYPH_OWN_BITMAP ) ) + { + FT_ERROR(( "ft_bsdf_render: can't generate SDF from" + " unowned source bitmap\n" )); + + error = FT_THROW( Invalid_Argument ); goto Exit; + } + + if ( !bitmap->rows || !bitmap->pitch ) + { + FT_ERROR(( "ft_bsdf_render: invalid bitmap size\n" )); + + error = FT_THROW( Invalid_Argument ); + goto Exit; + } FT_Bitmap_New( &target );