Bug 1442669 - guard against excessively large glyphs in SkFontHost_cairo. r=jfkthame

MozReview-Commit-ID: 1X2524Q5K8E
This commit is contained in:
Lee Salzman 2018-04-02 20:21:21 -04:00
Родитель 82c740d1b1
Коммит 0626b8ac56
1 изменённых файлов: 29 добавлений и 23 удалений

Просмотреть файл

@ -642,10 +642,19 @@ void SkScalerContext_CairoFT::generateMetrics(SkGlyph* glyph)
prepareGlyph(face->glyph); prepareGlyph(face->glyph);
if (fRec.fFlags & SkScalerContext::kVertical_Flag) {
glyph->fAdvanceX = -SkFDot6ToFloat(face->glyph->advance.x);
glyph->fAdvanceY = SkFDot6ToFloat(face->glyph->advance.y);
} else {
glyph->fAdvanceX = SkFDot6ToFloat(face->glyph->advance.x);
glyph->fAdvanceY = -SkFDot6ToFloat(face->glyph->advance.y);
}
SkIRect bounds;
switch (face->glyph->format) { switch (face->glyph->format) {
case FT_GLYPH_FORMAT_OUTLINE: case FT_GLYPH_FORMAT_OUTLINE:
if (!face->glyph->outline.n_contours) { if (!face->glyph->outline.n_contours) {
break; return;
} }
FT_BBox bbox; FT_BBox bbox;
@ -654,10 +663,10 @@ void SkScalerContext_CairoFT::generateMetrics(SkGlyph* glyph)
bbox.yMin &= ~63; bbox.yMin &= ~63;
bbox.xMax = (bbox.xMax + 63) & ~63; bbox.xMax = (bbox.xMax + 63) & ~63;
bbox.yMax = (bbox.yMax + 63) & ~63; bbox.yMax = (bbox.yMax + 63) & ~63;
glyph->fWidth = SkToU16(SkFDot6Floor(bbox.xMax - bbox.xMin)); bounds = SkIRect::MakeLTRB(SkFDot6Floor(bbox.xMin),
glyph->fHeight = SkToU16(SkFDot6Floor(bbox.yMax - bbox.yMin)); -SkFDot6Floor(bbox.yMax),
glyph->fTop = -SkToS16(SkFDot6Floor(bbox.yMax)); SkFDot6Floor(bbox.xMax),
glyph->fLeft = SkToS16(SkFDot6Floor(bbox.xMin)); -SkFDot6Floor(bbox.yMin));
if (isLCD(fRec)) { if (isLCD(fRec)) {
// In FreeType < 2.8.1, LCD filtering, if explicitly used, may // In FreeType < 2.8.1, LCD filtering, if explicitly used, may
@ -669,11 +678,9 @@ void SkScalerContext_CairoFT::generateMetrics(SkGlyph* glyph)
// here. generateGlyphImage will detect if the mask is smaller // here. generateGlyphImage will detect if the mask is smaller
// than the bounds and clip things appropriately. // than the bounds and clip things appropriately.
if (fRec.fFlags & kLCD_Vertical_Flag) { if (fRec.fFlags & kLCD_Vertical_Flag) {
glyph->fTop -= 1; bounds.outset(0, 1);
glyph->fHeight += 2;
} else { } else {
glyph->fLeft -= 1; bounds.outset(1, 0);
glyph->fWidth += 2;
} }
} }
break; break;
@ -702,15 +709,15 @@ void SkScalerContext_CairoFT::generateMetrics(SkGlyph* glyph)
SkRect destRect; SkRect destRect;
fShapeMatrix.mapRect(&destRect, srcRect); fShapeMatrix.mapRect(&destRect, srcRect);
SkIRect glyphRect = destRect.roundOut(); SkIRect glyphRect = destRect.roundOut();
glyph->fWidth = SkToU16(glyphRect.width()); bounds = SkIRect::MakeXYWH(SkScalarRoundToInt(destRect.fLeft),
glyph->fHeight = SkToU16(glyphRect.height()); SkScalarRoundToInt(destRect.fTop),
glyph->fTop = SkToS16(SkScalarRoundToInt(destRect.fTop)); glyphRect.width(),
glyph->fLeft = SkToS16(SkScalarRoundToInt(destRect.fLeft)); glyphRect.height());
} else { } else {
glyph->fWidth = SkToU16(face->glyph->bitmap.width); bounds = SkIRect::MakeXYWH(face->glyph->bitmap_left,
glyph->fHeight = SkToU16(face->glyph->bitmap.rows); -face->glyph->bitmap_top,
glyph->fTop = -SkToS16(face->glyph->bitmap_top); face->glyph->bitmap.width,
glyph->fLeft = SkToS16(face->glyph->bitmap_left); face->glyph->bitmap.rows);
} }
break; break;
default: default:
@ -718,12 +725,11 @@ void SkScalerContext_CairoFT::generateMetrics(SkGlyph* glyph)
return; return;
} }
if (fRec.fFlags & SkScalerContext::kVertical_Flag) { if (SkIRect::MakeXYWH(SHRT_MIN, SHRT_MIN, USHRT_MAX, USHRT_MAX).contains(bounds)) {
glyph->fAdvanceX = -SkFDot6ToFloat(face->glyph->advance.x); glyph->fWidth = SkToU16(bounds.width());
glyph->fAdvanceY = SkFDot6ToFloat(face->glyph->advance.y); glyph->fHeight = SkToU16(bounds.height());
} else { glyph->fLeft = SkToS16(bounds.left());
glyph->fAdvanceX = SkFDot6ToFloat(face->glyph->advance.x); glyph->fTop = SkToS16(bounds.top());
glyph->fAdvanceY = -SkFDot6ToFloat(face->glyph->advance.y);
} }
} }