Chromium Code Reviews| Index: skia/tools/path_fuzzer/path_fuzzer.cc |
| diff --git a/skia/tools/path_fuzzer/path_fuzzer.cc b/skia/tools/path_fuzzer/path_fuzzer.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..933b19ccdd957e62c8517d6e6566a0ca4cc30ef1 |
| --- /dev/null |
| +++ b/skia/tools/path_fuzzer/path_fuzzer.cc |
| @@ -0,0 +1,134 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include <stddef.h> |
| +#include <stdint.h> |
| + |
| +#include "third_party/skia/include/core/SkCanvas.h" |
| +#include "third_party/skia/include/core/SkPaint.h" |
| +#include "third_party/skia/include/core/SkPath.h" |
| +#include "third_party/skia/include/core/SkSurface.h" |
| + |
| +const int kOperationCount = 7; |
| + |
| +template <typename T> |
| +static bool read(const uint8_t** data, size_t* size, T* value) { |
| + if (*size < sizeof(T)) |
| + return false; |
| + |
| + *value = *reinterpret_cast<const T*>(*data); |
| + *data += sizeof(T); |
| + *size -= sizeof(T); |
| + return true; |
| +} |
| + |
| +void BuildPath(const uint8_t* data, size_t size, SkPath* path) { |
| + uint8_t operation; |
| + SkScalar a, b, c, d, e, f; |
| + while (read<uint8_t>(&data, &size, &operation)) { |
| + switch (operation % kOperationCount) { |
| + case 0: |
| + if (!read<SkScalar>(&data, &size, &a) || |
| + !read<SkScalar>(&data, &size, &b)) |
| + return; |
| + path->lineTo(a, b); |
| + break; |
| + |
| + case 1: |
| + if (!read<SkScalar>(&data, &size, &a) || |
| + !read<SkScalar>(&data, &size, &b) || |
| + !read<SkScalar>(&data, &size, &c) || |
| + !read<SkScalar>(&data, &size, &d)) |
| + return; |
| + path->quadTo(a, b, c, d); |
| + break; |
| + |
| + case 2: |
| + if (!read<SkScalar>(&data, &size, &a) || |
| + !read<SkScalar>(&data, &size, &b) || |
| + !read<SkScalar>(&data, &size, &c) || |
| + !read<SkScalar>(&data, &size, &d) || |
| + !read<SkScalar>(&data, &size, &e)) |
| + return; |
| + path->conicTo(a, b, c, d, e); |
| + break; |
| + |
| + case 3: |
| + if (!read<SkScalar>(&data, &size, &a) || |
| + !read<SkScalar>(&data, &size, &b) || |
| + !read<SkScalar>(&data, &size, &c) || |
| + !read<SkScalar>(&data, &size, &d) || |
| + !read<SkScalar>(&data, &size, &e) || |
| + !read<SkScalar>(&data, &size, &f)) |
| + return; |
| + path->cubicTo(a, b, c, d, e, f); |
| + break; |
| + |
| + case 5: |
| + if (!read<SkScalar>(&data, &size, &a) || |
| + !read<SkScalar>(&data, &size, &b)) |
| + return; |
| + path->moveTo(a, b); |
| + break; |
| + |
| + case 6: |
| + path->close(); |
| + break; |
| + } |
| + } |
| +} |
| + |
| +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { |
| + uint8_t w, h, anti_alias; |
| + if (!read<uint8_t>(&data, &size, &w)) |
| + return 0; |
| + if (!read<uint8_t>(&data, &size, &h)) |
| + return 0; |
| + if (!read<uint8_t>(&data, &size, &anti_alias)) |
| + return 0; |
| + |
| + SkScalar a, b, c, d; |
| + if (!read<SkScalar>(&data, &size, &a)) |
| + return 0; |
| + if (!read<SkScalar>(&data, &size, &b)) |
| + return 0; |
| + if (!read<SkScalar>(&data, &size, &c)) |
| + return 0; |
| + if (!read<SkScalar>(&data, &size, &d)) |
| + return 0; |
| + |
| + // SkPath::readFromMemory does not seem to be able to handle arbitrary input. |
| + SkPath path; |
| + BuildPath(data, size, &path); |
| + |
| + // Try a few potentially interesting things with our path. |
| + path.contains(a, b); |
| + path.conservativelyContainsRect(SkRect::MakeLTRB(a, b, c, d)); |
| + |
| + SkPaint paint_fill; |
| + paint_fill.setStyle(SkPaint::Style::kFill_Style); |
| + paint_fill.setAntiAlias(anti_alias & 1); |
| + |
| + SkPaint paint_stroke; |
| + paint_stroke.setStyle(SkPaint::Style::kStroke_Style); |
| + paint_stroke.setStrokeWidth(1); |
| + paint_stroke.setAntiAlias(anti_alias & 1); |
| + |
| + SkPaint paint_stroke_and_fill; |
| + paint_stroke_and_fill.setStyle(SkPaint::Style::kStrokeAndFill_Style); |
| + paint_stroke_and_fill.setStrokeWidth(1); |
| + paint_stroke_and_fill.setAntiAlias(anti_alias & 1); |
| + |
| + SkPath dst_path; |
| + paint_stroke.getFillPath(path, &dst_path, nullptr); |
| + |
| + // Width and height should never be 0. |
| + auto surface(SkSurface::MakeRasterN32Premul(w + 1, h + 1)); |
|
mmoroz
2016/06/03 13:52:14
Since MakeRasterN32Premul() accepts int arguments,
Martin Barbella
2016/06/03 20:10:38
Went with x ? x : 1 instead in the extremely unlik
|
| + |
| + surface->getCanvas()->drawPath(path, paint_fill); |
| + surface->getCanvas()->drawPath(path, paint_stroke); |
| + surface->getCanvas()->drawPath(path, paint_stroke_and_fill); |
| + |
| + return 0; |
| +} |