| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include <stddef.h> |
| 6 #include <stdint.h> |
| 7 |
| 8 #include "third_party/skia/include/core/SkCanvas.h" |
| 9 #include "third_party/skia/include/core/SkPaint.h" |
| 10 #include "third_party/skia/include/core/SkPath.h" |
| 11 #include "third_party/skia/include/core/SkSurface.h" |
| 12 |
| 13 // We specifically don't want to include kDone_Verb. |
| 14 const int kLastVerb = SkPath::Verb::kClose_Verb; |
| 15 |
| 16 template <typename T> |
| 17 static bool read(const uint8_t** data, size_t* size, T* value) { |
| 18 if (*size < sizeof(T)) |
| 19 return false; |
| 20 |
| 21 *value = *reinterpret_cast<const T*>(*data); |
| 22 *data += sizeof(T); |
| 23 *size -= sizeof(T); |
| 24 return true; |
| 25 } |
| 26 |
| 27 void BuildPath(const uint8_t* data, size_t size, SkPath* path) { |
| 28 uint8_t operation; |
| 29 SkScalar a, b, c, d, e, f; |
| 30 while (read<uint8_t>(&data, &size, &operation)) { |
| 31 switch (operation % (kLastVerb + 1)) { |
| 32 case SkPath::Verb::kMove_Verb: |
| 33 if (!read<SkScalar>(&data, &size, &a) || |
| 34 !read<SkScalar>(&data, &size, &b)) |
| 35 return; |
| 36 path->moveTo(a, b); |
| 37 break; |
| 38 |
| 39 case SkPath::Verb::kLine_Verb: |
| 40 if (!read<SkScalar>(&data, &size, &a) || |
| 41 !read<SkScalar>(&data, &size, &b)) |
| 42 return; |
| 43 path->lineTo(a, b); |
| 44 break; |
| 45 |
| 46 case SkPath::Verb::kQuad_Verb: |
| 47 if (!read<SkScalar>(&data, &size, &a) || |
| 48 !read<SkScalar>(&data, &size, &b) || |
| 49 !read<SkScalar>(&data, &size, &c) || |
| 50 !read<SkScalar>(&data, &size, &d)) |
| 51 return; |
| 52 path->quadTo(a, b, c, d); |
| 53 break; |
| 54 |
| 55 case SkPath::Verb::kConic_Verb: |
| 56 if (!read<SkScalar>(&data, &size, &a) || |
| 57 !read<SkScalar>(&data, &size, &b) || |
| 58 !read<SkScalar>(&data, &size, &c) || |
| 59 !read<SkScalar>(&data, &size, &d) || |
| 60 !read<SkScalar>(&data, &size, &e)) |
| 61 return; |
| 62 path->conicTo(a, b, c, d, e); |
| 63 break; |
| 64 |
| 65 case SkPath::Verb::kCubic_Verb: |
| 66 if (!read<SkScalar>(&data, &size, &a) || |
| 67 !read<SkScalar>(&data, &size, &b) || |
| 68 !read<SkScalar>(&data, &size, &c) || |
| 69 !read<SkScalar>(&data, &size, &d) || |
| 70 !read<SkScalar>(&data, &size, &e) || |
| 71 !read<SkScalar>(&data, &size, &f)) |
| 72 return; |
| 73 path->cubicTo(a, b, c, d, e, f); |
| 74 break; |
| 75 |
| 76 case SkPath::Verb::kClose_Verb: |
| 77 path->close(); |
| 78 break; |
| 79 } |
| 80 } |
| 81 } |
| 82 |
| 83 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { |
| 84 uint8_t w, h, anti_alias; |
| 85 if (!read<uint8_t>(&data, &size, &w)) |
| 86 return 0; |
| 87 if (!read<uint8_t>(&data, &size, &h)) |
| 88 return 0; |
| 89 if (!read<uint8_t>(&data, &size, &anti_alias)) |
| 90 return 0; |
| 91 |
| 92 SkScalar a, b, c, d; |
| 93 if (!read<SkScalar>(&data, &size, &a)) |
| 94 return 0; |
| 95 if (!read<SkScalar>(&data, &size, &b)) |
| 96 return 0; |
| 97 if (!read<SkScalar>(&data, &size, &c)) |
| 98 return 0; |
| 99 if (!read<SkScalar>(&data, &size, &d)) |
| 100 return 0; |
| 101 |
| 102 // SkPath::readFromMemory does not seem to be able to handle arbitrary input. |
| 103 SkPath path; |
| 104 BuildPath(data, size, &path); |
| 105 |
| 106 // Try a few potentially interesting things with our path. |
| 107 path.contains(a, b); |
| 108 path.conservativelyContainsRect(SkRect::MakeLTRB(a, b, c, d)); |
| 109 |
| 110 SkPaint paint_fill; |
| 111 paint_fill.setStyle(SkPaint::Style::kFill_Style); |
| 112 paint_fill.setAntiAlias(anti_alias & 1); |
| 113 |
| 114 SkPaint paint_stroke; |
| 115 paint_stroke.setStyle(SkPaint::Style::kStroke_Style); |
| 116 paint_stroke.setStrokeWidth(1); |
| 117 paint_stroke.setAntiAlias(anti_alias & 1); |
| 118 |
| 119 SkPaint paint_stroke_and_fill; |
| 120 paint_stroke_and_fill.setStyle(SkPaint::Style::kStrokeAndFill_Style); |
| 121 paint_stroke_and_fill.setStrokeWidth(1); |
| 122 paint_stroke_and_fill.setAntiAlias(anti_alias & 1); |
| 123 |
| 124 SkPath dst_path; |
| 125 paint_stroke.getFillPath(path, &dst_path, nullptr); |
| 126 |
| 127 // Width and height should never be 0. |
| 128 auto surface(SkSurface::MakeRasterN32Premul(w ? w : 1, h ? h : 1)); |
| 129 |
| 130 surface->getCanvas()->drawPath(path, paint_fill); |
| 131 surface->getCanvas()->drawPath(path, paint_stroke); |
| 132 surface->getCanvas()->drawPath(path, paint_stroke_and_fill); |
| 133 |
| 134 return 0; |
| 135 } |
| OLD | NEW |