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.h"
9 #include "SkPath.h"
10 #include "SkPathOps.h"
11 
12 const int kLastOp = SkPathOp::kReverseDifference_SkPathOp;
13 
BuildPath(Fuzz * fuzz,SkPath * path,int last_verb)14 void BuildPath(Fuzz* fuzz,
15                SkPath* path,
16                int last_verb) {
17   while (!fuzz->exhausted()) {
18     // Use a uint8_t to conserve bytes.  This makes our "fuzzed bytes footprint"
19     // smaller, which leads to more efficient fuzzing.
20     uint8_t operation;
21     fuzz->next(&operation);
22     SkScalar a,b,c,d,e,f;
23 
24     switch (operation % (last_verb + 1)) {
25       case SkPath::Verb::kMove_Verb:
26         fuzz->next(&a, &b);
27         path->moveTo(a, b);
28         break;
29 
30       case SkPath::Verb::kLine_Verb:
31         fuzz->next(&a, &b);
32         path->lineTo(a, b);
33         break;
34 
35       case SkPath::Verb::kQuad_Verb:
36         fuzz->next(&a, &b, &c, &d);
37         path->quadTo(a, b, c, d);
38         break;
39 
40       case SkPath::Verb::kConic_Verb:
41         fuzz->next(&a, &b, &c, &d, &e);
42         path->conicTo(a, b, c, d, e);
43         break;
44 
45       case SkPath::Verb::kCubic_Verb:
46         fuzz->next(&a, &b, &c, &d, &e, &f);
47         path->cubicTo(a, b, c, d, e, f);
48         break;
49 
50       case SkPath::Verb::kClose_Verb:
51         path->close();
52         break;
53 
54       case SkPath::Verb::kDone_Verb:
55         // In this case, simply exit.
56         return;
57     }
58   }
59 }
60 
DEF_FUZZ(Pathop,fuzz)61 DEF_FUZZ(Pathop, fuzz) {
62     SkOpBuilder builder;
63 
64     uint8_t stragglerOp;
65     fuzz->next(&stragglerOp);
66     SkPath path;
67 
68     BuildPath(fuzz, &path, SkPath::Verb::kDone_Verb);
69     builder.add(path, static_cast<SkPathOp>(stragglerOp % (kLastOp + 1)));
70 
71     SkPath result;
72     builder.resolve(&result);
73 }
74