From a0115cde400a51b8b9a0c9206dec3391dd461e15 Mon Sep 17 00:00:00 2001 From: Dom Chen Date: Thu, 21 Mar 2024 20:04:55 +0800 Subject: [PATCH] Fix the out-of-bounds memory access issue in the FTMask class. --- src/vectors/freetype/FTMask.cpp | 34 ++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/src/vectors/freetype/FTMask.cpp b/src/vectors/freetype/FTMask.cpp index a96329b6..e1346acb 100644 --- a/src/vectors/freetype/FTMask.cpp +++ b/src/vectors/freetype/FTMask.cpp @@ -65,10 +65,7 @@ struct RasterTarget { static void SpanFunc(int y, int, const FT_Span* spans, void* user) { auto* target = reinterpret_cast(user); auto* q = target->origin - target->pitch * y + spans->x; - auto c = spans->coverage; - if (target->gammaTable) { - c = target->gammaTable[c]; - } + auto c = target->gammaTable[spans->coverage]; auto aCount = spans->len; /** * For small-spans it is faster to do it by ourselves than calling memset. @@ -118,21 +115,36 @@ void FTMask::onFillPath(const Path& path, const Matrix& matrix, bool needsGammaC ftPath.setFillType(path.getFillType()); auto outlines = ftPath.getOutlines(); auto ftLibrary = GetLibrary().library(); + if (!needsGammaCorrection) { + FT_Bitmap bitmap; + bitmap.width = static_cast(info.width()); + bitmap.rows = static_cast(info.height()); + bitmap.pitch = static_cast(info.rowBytes()); + bitmap.buffer = static_cast(pixels); + bitmap.pixel_mode = FT_PIXEL_MODE_GRAY; + bitmap.num_grays = 256; + for (auto& outline : outlines) { + FT_Outline_Get_Bitmap(ftLibrary, &(outline->outline), &bitmap); + } + pixelRef->unlockPixels(); + return; + } auto buffer = static_cast(pixels); int rows = info.height(); int pitch = static_cast(info.rowBytes()); - RasterTarget target{}; + RasterTarget target = {}; target.origin = buffer + (rows - 1) * pitch; target.pitch = pitch; - if (needsGammaCorrection) { - target.gammaTable = PixelRefMask::GammaTable().data(); - } else { - target.gammaTable = nullptr; - } + target.gammaTable = PixelRefMask::GammaTable().data(); FT_Raster_Params params; - params.flags = FT_RASTER_FLAG_AA | FT_RASTER_FLAG_DIRECT; + params.flags = FT_RASTER_FLAG_AA | FT_RASTER_FLAG_DIRECT | FT_RASTER_FLAG_CLIP; params.gray_spans = SpanFunc; params.user = ⌖ + auto& clip = params.clip_box; + clip.xMin = 0; + clip.yMin = 0; + clip.xMax = (FT_Pos)info.width(); + clip.yMax = (FT_Pos)info.height(); for (auto& outline : outlines) { FT_Outline_Render(ftLibrary, &(outline->outline), ¶ms); }