Flutter Engine
The Flutter Engine
FuzzPathop.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2016 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "fuzz/Fuzz.h"
9#include "fuzz/FuzzCommon.h"
10#include "include/core/SkPath.h"
11#include "include/core/SkRect.h"
13
14const uint8_t MAX_OPS = 20;
15
16DEF_FUZZ(Pathop, fuzz) {
17
18 uint8_t choice;
19 fuzz->nextRange(&choice, 0, 4);
20 switch (choice) {
21 case 0: {
22 uint8_t ops;
23 fuzz->nextRange(&ops, 0, MAX_OPS);
25 for (uint8_t i = 0; i < ops && !fuzz->exhausted(); i++) {
27 FuzzEvilPath(fuzz, &path, SkPath::Verb::kDone_Verb);
29 fuzz->nextRange(&ft, 0, (int)SkPathFillType::kInverseEvenOdd);
30 path.setFillType(ft);
31
32 SkPathOp op;
33 fuzz->nextRange(&op, 0, SkPathOp::kReverseDifference_SkPathOp);
34 builder.add(path, op);
35 }
36
38 builder.resolve(&result);
39 break;
40 }
41 case 1: {
43 FuzzEvilPath(fuzz, &path, SkPath::Verb::kDone_Verb);
45 fuzz->nextRange(&ft, 0, (int)SkPathFillType::kInverseEvenOdd);
46 path.setFillType(ft);
47
49 bool isSame;
50 fuzz->next(&isSame);
51 if (isSame) {
52 result = path;
53 }
55 break;
56 }
57 case 2: {
59 FuzzEvilPath(fuzz, &path, SkPath::Verb::kDone_Verb);
61 fuzz->nextRange(&ft, 0, SkPathFillType::kInverseEvenOdd);
62 path.setFillType(ft);
63
65 FuzzEvilPath(fuzz, &path2, SkPath::Verb::kDone_Verb);
66 fuzz->nextRange(&ft, 0, SkPathFillType::kInverseEvenOdd);
67 path.setFillType(ft);
68
69 SkPathOp op;
70 fuzz->nextRange(&op, 0, SkPathOp::kReverseDifference_SkPathOp);
71
73 uint8_t pickOutput;
74 fuzz->nextRange(&pickOutput, 0, 2);
75 if (pickOutput == 1) {
76 result = path;
77 } else if (pickOutput == 2) {
78 result = path2;
79 }
80 Op(path, path2, op, &result);
81 break;
82 }
83 case 3: {
85 FuzzEvilPath(fuzz, &path, SkPath::Verb::kDone_Verb);
87 fuzz->nextRange(&ft, 0, SkPathFillType::kInverseEvenOdd);
88 path.setFillType(ft);
89
91 bool isSame;
92 fuzz->next(&isSame);
93 if (isSame) {
94 result = path;
95 }
97 break;
98 }
99 case 4: {
100 SkPath path;
101 FuzzEvilPath(fuzz, &path, SkPath::Verb::kDone_Verb);
103 fuzz->nextRange(&ft, 0, SkPathFillType::kInverseEvenOdd);
104 path.setFillType(ft);
105
108 break;
109 }
110 default: {
111 SkASSERT(false);
112 break;
113 }
114 }
115}
116
117
119
120void BuildPath(Fuzz* fuzz, SkPath* path) {
121 while (!fuzz->exhausted()) {
122 // Use a uint8_t to conserve bytes. This makes our "fuzzed bytes footprint"
123 // smaller, which leads to more efficient fuzzing.
124 uint8_t operation;
125 fuzz->next(&operation);
126 SkScalar a,b,c,d,e,f;
127
128 switch (operation % (SkPath::Verb::kDone_Verb + 1)) {
129 case SkPath::Verb::kMove_Verb:
130 if (fuzz->remainingSize() < (2*sizeof(SkScalar))) {
131 fuzz->deplete();
132 return;
133 }
134 fuzz->next(&a, &b);
135 path->moveTo(a, b);
136 break;
137
138 case SkPath::Verb::kLine_Verb:
139 if (fuzz->remainingSize() < (2*sizeof(SkScalar))) {
140 fuzz->deplete();
141 return;
142 }
143 fuzz->next(&a, &b);
144 path->lineTo(a, b);
145 break;
146
147 case SkPath::Verb::kQuad_Verb:
148 if (fuzz->remainingSize() < (4*sizeof(SkScalar))) {
149 fuzz->deplete();
150 return;
151 }
152 fuzz->next(&a, &b, &c, &d);
153 path->quadTo(a, b, c, d);
154 break;
155
156 case SkPath::Verb::kConic_Verb:
157 if (fuzz->remainingSize() < (5*sizeof(SkScalar))) {
158 fuzz->deplete();
159 return;
160 }
161 fuzz->next(&a, &b, &c, &d, &e);
162 path->conicTo(a, b, c, d, e);
163 break;
164
165 case SkPath::Verb::kCubic_Verb:
166 if (fuzz->remainingSize() < (6*sizeof(SkScalar))) {
167 fuzz->deplete();
168 return;
169 }
170 fuzz->next(&a, &b, &c, &d, &e, &f);
171 path->cubicTo(a, b, c, d, e, f);
172 break;
173
174 case SkPath::Verb::kClose_Verb:
175 path->close();
176 break;
177
178 case SkPath::Verb::kDone_Verb:
179 // In this case, simply exit.
180 return;
181 }
182 }
183}
184
185DEF_FUZZ(LegacyChromiumPathop, fuzz) {
186 // See https://cs.chromium.org/chromium/src/testing/libfuzzer/fuzzers/skia_pathop_fuzzer.cc
188 while (!fuzz->exhausted()) {
189 SkPath path;
190 uint8_t op;
191 fuzz->next(&op);
192 if (fuzz->exhausted()) {
193 break;
194 }
195
196 BuildPath(fuzz, &path);
197 builder.add(path, static_cast<SkPathOp>(op % (kLastOp + 1)));
198 }
199
201 builder.resolve(&result);
202}
void FuzzEvilPath(Fuzz *fuzz, SkPath *path, int last_verb)
Definition: FuzzCommon.cpp:237
DEF_FUZZ(Pathop, fuzz)
Definition: FuzzPathop.cpp:16
void BuildPath(Fuzz *fuzz, SkPath *path)
Definition: FuzzPathop.cpp:120
const uint8_t MAX_OPS
Definition: FuzzPathop.cpp:14
const int kLastOp
Definition: FuzzPathop.cpp:118
static SkPath path2()
SkPathOp ops[]
#define SkASSERT(cond)
Definition: SkAssert.h:116
static void operation(T operation, uint32_t &a, uint32_t b, uint32_t c, uint32_t d, uint32_t x, uint8_t s, uint32_t t)
Definition: SkMD5.cpp:144
bool SK_API AsWinding(const SkPath &path, SkPath *result)
SkPathOp
Definition: SkPathOps.h:22
@ kReverseDifference_SkPathOp
subtract the first path from the op path
Definition: SkPathOps.h:27
bool SK_API Simplify(const SkPath &path, SkPath *result)
bool SK_API TightBounds(const SkPath &path, SkRect *result)
SkPathFillType
Definition: SkPathTypes.h:11
Definition: Fuzz.h:24
void next(T *t)
Definition: Fuzz.h:64
size_t remainingSize() const
Definition: Fuzz.h:47
void deplete()
Definition: Fuzz.h:43
bool exhausted() const
Definition: Fuzz.h:39
Definition: SkPath.h:59
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition: main.cc:19
float SkScalar
Definition: extension.cpp:12
static bool b
struct MyStruct a[10]
GAsyncResult * result
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57