From fec1dea8098fe09f04fff542efdb83edc1fe8240 Mon Sep 17 00:00:00 2001 From: Kevin Lubick Date: Tue, 22 Nov 2016 13:57:18 -0500 Subject: FuzzDrawFunctions from twsmith BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=4979 Change-Id: Ib5cc6ea036538b611d6959c679a276050e145f57 Reviewed-on: https://skia-review.googlesource.com/4979 Reviewed-by: Mike Klein --- fuzz/FuzzDrawFunctions.cpp | 358 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 358 insertions(+) create mode 100644 fuzz/FuzzDrawFunctions.cpp (limited to 'fuzz/FuzzDrawFunctions.cpp') diff --git a/fuzz/FuzzDrawFunctions.cpp b/fuzz/FuzzDrawFunctions.cpp new file mode 100644 index 0000000000..b73bbf9217 --- /dev/null +++ b/fuzz/FuzzDrawFunctions.cpp @@ -0,0 +1,358 @@ +/* + * Copyright 2016 Mozilla Foundation + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "Fuzz.h" +#include "SkBitmap.h" +#include "SkCanvas.h" +#include "SkImage.h" +#include "SkLayerRasterizer.h" +#include "SkPath.h" +#include "SkSurface.h" +#include "SkTypeface.h" + +static const int kBmpSize = 24; +static const int kMaxX = 250; +static const int kMaxY = 250; +static const int kPtsLen = 10; +static const int kTxtLen = 5; + +static void init_bitmap(Fuzz* fuzz, SkBitmap* bmp) { + uint8_t colorType; + fuzz->nextRange(&colorType, 0, (int)kLastEnum_SkColorType); + SkImageInfo info = SkImageInfo::Make(kBmpSize, + kBmpSize, + (SkColorType)colorType, + kPremul_SkAlphaType); + if (!bmp->tryAllocPixels(info)) { + SkDebugf("Bitmap not allocated\n"); + } + bool b; + fuzz->next(&b); + if (b) { // initialize + SkCanvas canvas(*bmp); + canvas.clear(0); + SkColor c; + fuzz->next(&c); + SkPaint p; // TODO: maybe init_paint? + p.setColor(c); + canvas.drawRect(SkRect::MakeXYWH(0, 0, kBmpSize, kBmpSize), p); + } +} + +static void init_string(Fuzz* fuzz, char* str, size_t bufSize) { + for (size_t i = 0; i < bufSize-1; ++i) { + fuzz->nextRange(&str[i], 0x20, 0x7E); // printable ASCII + } + str[bufSize-1] = '\0'; +} + +// make_paint mostly borrowed from FilterFuzz.cpp +static void init_paint(Fuzz* fuzz, SkPaint* p) { + bool b; + fuzz->next(&b); + p->setAntiAlias(b); + + uint8_t tmp_u8; + fuzz->nextRange(&tmp_u8, 0, (int)SkBlendMode::kLastMode); + p->setBlendMode(static_cast(tmp_u8)); + + SkColor co; + fuzz->next(&co); + p->setColor(co); + + fuzz->next(&b); + p->setDither(b); + + fuzz->nextRange(&tmp_u8, 0, (int)kHigh_SkFilterQuality); + p->setFilterQuality(static_cast(tmp_u8)); + + fuzz->nextRange(&tmp_u8, 0, (int)SkPaint::kFull_Hinting); + p->setHinting(static_cast(tmp_u8)); + + fuzz->nextRange(&tmp_u8, 0, (int)SkPaint::kLast_Cap); + p->setStrokeCap(static_cast(tmp_u8)); + + fuzz->nextRange(&tmp_u8, 0, (int)SkPaint::kLast_Join); + p->setStrokeJoin(static_cast(tmp_u8)); + + SkScalar sc; + fuzz->next(&sc); + p->setStrokeMiter(sc); + + fuzz->next(&sc); + p->setStrokeWidth(sc); + + fuzz->nextRange(&tmp_u8, 0, (int)SkPaint::kStrokeAndFill_Style); + p->setStyle(static_cast(tmp_u8)); +} + + +static void init_surface(Fuzz* fuzz, sk_sp* s) { + uint8_t x, y; + fuzz->nextRange(&x, 1, kMaxX); + fuzz->nextRange(&y, 1, kMaxY); + *s = SkSurface::MakeRasterN32Premul(x, y); +} + + +static void fuzz_drawText(Fuzz* fuzz, sk_sp font) { + SkPaint p; + init_paint(fuzz, &p); + sk_sp surface; + init_surface(fuzz, &surface); + + char text[kTxtLen]; + init_string(fuzz, text, kTxtLen); + + SkScalar x, y; + fuzz->next(&x, &y); + // populate pts array + SkPoint pts[kPtsLen]; + for (uint8_t i = 0; i < kPtsLen; ++i) { + pts[i].set(x, y); + x += p.getTextSize(); + } + + p.setTypeface(font); + // set text related attributes + bool b; + fuzz->next(&b); + p.setAutohinted(b); + fuzz->next(&b); + p.setDevKernText(b); + fuzz->next(&b); + p.setEmbeddedBitmapText(b); + fuzz->next(&b); + p.setFakeBoldText(b); + fuzz->next(&b); + p.setLCDRenderText(b); + fuzz->next(&b); + p.setLinearText(b); + fuzz->next(&b); + p.setStrikeThruText(b); + fuzz->next(&b); + p.setSubpixelText(b); + fuzz->next(&x); + p.setTextScaleX(x); + fuzz->next(&x); + p.setTextSkewX(x); + fuzz->next(&x); + p.setTextSize(x); + fuzz->next(&b); + p.setUnderlineText(b); + fuzz->next(&b); + p.setVerticalText(b); + + SkCanvas* cnv = surface->getCanvas(); + cnv->drawPosText(text, (kTxtLen-1), pts, p); + + fuzz->next(&x); + fuzz->next(&y); + cnv->drawText(text, (kTxtLen-1), x, y, p); +} + +static void fuzz_drawCircle(Fuzz* fuzz) { + SkPaint p; + init_paint(fuzz, &p); + sk_sp surface; + init_surface(fuzz, &surface); + + SkScalar a, b, c; + fuzz->next(&a, &b, &c); + surface->getCanvas()->drawCircle(a, b, c, p); +} + +static void fuzz_drawLine(Fuzz* fuzz) { + SkPaint p; + init_paint(fuzz, &p); + sk_sp surface; + init_surface(fuzz, &surface); + + SkScalar a, b, c, d; + fuzz->next(&a, &b, &c, &d); + surface->getCanvas()->drawLine(a, b, c, d, p); +} + +static void fuzz_drawRect(Fuzz* fuzz) { + SkPaint p; + init_paint(fuzz, &p); + sk_sp surface; + init_surface(fuzz, &surface); + + SkScalar a, b, c, d; + fuzz->next(&a, &b, &c, &d); + SkRect r; + r = SkRect::MakeXYWH(a, b, c, d); + + SkCanvas* cnv = surface->getCanvas(); + cnv->drawRect(r, p); + + bool bl; + fuzz->next(&bl); + fuzz->next(&a, &b, &c, &d); + r = SkRect::MakeXYWH(a, b, c, d); + cnv->clipRect(r, SkCanvas::kIntersect_Op, bl); +} + +static void fuzz_drawPath(Fuzz* fuzz) { + SkPaint p; + init_paint(fuzz, &p); + sk_sp surface; + init_surface(fuzz, &surface); + + // TODO(kjlubick): put the ability to fuzz a path in shared file, with + // other common things (e.g. rects, lines) + uint8_t i, j; + fuzz->nextRange(&i, 0, 10); // set i to number of operations to perform + SkPath path; + SkScalar a, b, c, d, e, f; + for (int k = 0; k < i; ++k) { + fuzz->nextRange(&j, 0, 5); // set j to choose operation to perform + switch (j) { + case 0: + fuzz->next(&a, &b); + path.moveTo(a, b); + break; + case 1: + fuzz->next(&a, &b); + path.lineTo(a, b); + break; + case 2: + fuzz->next(&a, &b, &c, &d); + path.quadTo(a, b, c, d); + break; + case 3: + fuzz->next(&a, &b, &c, &d, &e); + path.conicTo(a, b, c, d, e); + break; + case 4: + fuzz->next(&a, &b, &c, &d, &e, &f); + path.cubicTo(a, b, c, d, e, f); + break; + case 5: + fuzz->next(&a, &b, &c, &d, &e); + path.arcTo(a, b, c, d, e); + break; + } + } + path.close(); + + SkCanvas* cnv = surface->getCanvas(); + cnv->drawPath(path, p); + + bool bl; + fuzz->next(&bl); + cnv->clipPath(path, SkCanvas::kIntersect_Op, bl); +} + +static void fuzz_drawBitmap(Fuzz* fuzz) { + SkPaint p; + init_paint(fuzz, &p); + sk_sp surface; + init_surface(fuzz, &surface); + SkBitmap bmp; + init_bitmap(fuzz, &bmp); + + SkScalar a, b; + fuzz->next(&a, &b); + surface->getCanvas()->drawBitmap(bmp, a, b, &p); +} + +static void fuzz_drawImage(Fuzz* fuzz) { + SkPaint p; + init_paint(fuzz, &p); + sk_sp surface; + init_surface(fuzz, &surface); + SkBitmap bmp; + init_bitmap(fuzz, &bmp); + + sk_sp image(SkImage::MakeFromBitmap(bmp)); + + bool bl; + fuzz->next(&bl); + SkScalar a, b; + fuzz->next(&a, &b); + if (bl) { + surface->getCanvas()->drawImage(image, a, b, &p); + } + else { + SkRect dst = SkRect::MakeWH(a, b); + fuzz->next(&a, &b); + SkRect src = SkRect::MakeWH(a, b); + uint8_t x; + fuzz->nextRange(&x, 0, 1); + SkCanvas::SrcRectConstraint cst = (SkCanvas::SrcRectConstraint)x; + surface->getCanvas()->drawImageRect(image, src, dst, &p, cst); + } +} + +static void fuzz_drawPaint(Fuzz* fuzz) { + SkPaint l, p; + init_paint(fuzz, &p); + sk_sp surface; + init_surface(fuzz, &surface); + + // add layers + uint8_t x; + fuzz->nextRange(&x, 1, 3); // max 3 layers + SkLayerRasterizer::Builder builder; + for (int i = 0; i < x; i++) { + init_paint(fuzz, &l); + builder.addLayer(l); + } + + sk_sp raster(builder.detach()); + p.setRasterizer(raster); + + surface->getCanvas()->drawPaint(p); +} + +DEF_FUZZ(DrawFunctions, fuzz) { + uint8_t i; + fuzz->next(&i); + + switch(i) { + case 0: { + sk_sp f = SkTypeface::MakeDefault(); + if (f == nullptr) { + SkDebugf("Could not initialize font.\n"); + fuzz->signalBug(); + } + SkDebugf("Fuzz DrawText\n"); + fuzz_drawText(fuzz, f); + return; + } + case 1: + SkDebugf("Fuzz DrawRect\n"); + fuzz_drawRect(fuzz); + return; + case 2: + SkDebugf("Fuzz DrawCircle\n"); + fuzz_drawCircle(fuzz); + return; + case 3: + SkDebugf("Fuzz DrawLine\n"); + fuzz_drawLine(fuzz); + return; + case 4: + SkDebugf("Fuzz DrawPath\n"); + fuzz_drawPath(fuzz); + return; + case 5: + SkDebugf("Fuzz DrawImage/DrawImageRect\n"); + fuzz_drawImage(fuzz); + return; + case 6: + SkDebugf("Fuzz DrawBitmap\n"); + fuzz_drawBitmap(fuzz); + return; + case 7: + SkDebugf("Fuzz DrawPaint\n"); + fuzz_drawPaint(fuzz); + return; + } +} -- cgit v1.2.3