don't draw strings that have no glyphs

This string had several characters which resulted in zero
glyphs. Having zero glyphs bypassed the buffer sizing code,
and continued to process the glyph run list assuming it had
7 runs because the buffer sizing code also clears the run list.
This caused the code to process runs from a previous SkTextBlob,
which was already deleted.

If the there are no glyphs, call the buffer sizing code to
set up all the invariants. Exit if there are no runs produced.

Bug: oss-fuzz:33915

Change-Id: I9f3f38a58112c44ddd65265c68d982b3b0dcd79c
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/403439
Reviewed-by: Ben Wagner <bungeman@google.com>
Commit-Queue: Herb Derby <herb@google.com>
This commit is contained in:
Herb Derby 2021-05-03 10:46:47 -04:00 committed by Skia Commit-Bot
parent 4ecc0f43f2
commit b6cce2d4c7
3 changed files with 21 additions and 2 deletions

View File

@ -2279,7 +2279,9 @@ void SkCanvas::drawSimpleText(const void* text, size_t byteLength, SkTextEncodin
const SkGlyphRunList& glyphRunList =
fScratchGlyphRunBuilder->textToGlyphRunList(
font, paint, text, byteLength, {x, y}, encoding);
this->onDrawGlyphRunList(glyphRunList, paint);
if (!glyphRunList.empty()) {
this->onDrawGlyphRunList(glyphRunList, paint);
}
}
}

View File

@ -193,8 +193,8 @@ const SkGlyphRunList& SkGlyphRunBuilder::textToGlyphRunList(
SkTextEncoding encoding) {
auto glyphIDs = textToGlyphIDs(font, bytes, byteLength, encoding);
SkRect bounds = SkRect::MakeEmpty();
this->prepareBuffers(glyphIDs.size(), 0);
if (!glyphIDs.empty()) {
this->prepareBuffers(glyphIDs.size(), 0);
SkSpan<const SkPoint> positions = draw_text_positions(font, glyphIDs, {0, 0}, fPositions);
this->makeGlyphRun(font,
glyphIDs,

View File

@ -17,6 +17,7 @@
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTextBlob.h"
#include "include/core/SkTypeface.h"
#include "include/core/SkTypes.h"
#include "include/effects/SkDashPathEffect.h"
@ -161,3 +162,19 @@ DEF_TEST(DrawText_weirdMatricies, r) {
canvas->drawString("Hamburgefons", 10, 10, font, SkPaint());
}
}
// This produces no glyphs, and is to check that buffers from previous draws don't get
// reused.
DEF_TEST(DrawText_noglyphs, r) {
auto surface = SkSurface::MakeRasterN32Premul(100,100);
auto canvas = surface->getCanvas();
auto text = "Hamburgfons";
{
// scoped to ensure blob is deleted.
auto blob = SkTextBlob::MakeFromText(text, strlen(text), SkFont());
canvas->drawTextBlob(blob, 10, 10, SkPaint());
}
canvas->drawString(
"\x0d\xf3\xf2\xf2\xe9\x0d\x0d\x0d\x05\x0d\x0d\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3\xe3",
10, 20, SkFont(), SkPaint());
}