blob: b9d7f6b418a1464f9fad9837b9c39d34c1377ffa [file] [log] [blame]
kjlubick5bd98a22016-02-18 06:27:38 -08001/*
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 "SkString.h"
10#include "SkParsePath.h"
11#include <stdlib.h>
12
13// Most of this is taken from random_parse_path.cpp and adapted to use the Fuzz
14// instead of SKRandom
15
kjlubick14f984b2016-10-03 11:49:45 -070016static const struct Legal {
kjlubick5bd98a22016-02-18 06:27:38 -080017 char fSymbol;
18 int fScalars;
19} gLegal[] = {
20 { 'M', 2 },
21 { 'H', 1 },
22 { 'V', 1 },
23 { 'L', 2 },
24 { 'Q', 4 },
25 { 'T', 2 },
26 { 'C', 6 },
27 { 'S', 4 },
28 { 'A', 4 },
29 { 'Z', 0 },
30};
31
kjlubick14f984b2016-10-03 11:49:45 -070032static bool gEasy = false; // set to true while debugging to suppress unusual whitespace
kjlubick5bd98a22016-02-18 06:27:38 -080033
34// mostly do nothing, then bias towards spaces
kjlubick14f984b2016-10-03 11:49:45 -070035static const char gWhiteSpace[] = { 0, 0, 0, 0, 0, 0, 0, 0, ' ', ' ', ' ', ' ', 0x09, 0x0D, 0x0A };
kjlubick5bd98a22016-02-18 06:27:38 -080036
37static void add_white(Fuzz* fuzz, SkString* atom) {
38 if (gEasy) {
39 atom->append(" ");
40 return;
41 }
Kevin Lubick416b2482016-11-10 16:17:49 -050042 // Use a uint8_t to conserve bytes. This makes our "fuzzed bytes footprint"
43 // smaller, which leads to more efficient fuzzing.
44 uint8_t reps;
45 fuzz->nextRange(&reps, 0, 2);
46 for (uint8_t rep = 0; rep < reps; ++rep) {
47 uint8_t index;
Kevin Lubickc9f0cc82016-11-15 16:07:02 -050048 fuzz->nextRange(&index, 0, (int) SK_ARRAY_COUNT(gWhiteSpace) - 1);
kjlubick5bd98a22016-02-18 06:27:38 -080049 if (gWhiteSpace[index]) {
50 atom->append(&gWhiteSpace[index], 1);
51 }
52 }
53}
54
Kevin Lubick2f535ce2016-11-01 15:01:12 -040055static void add_some_white(Fuzz* fuzz, SkString* atom) {
56 for(int i = 0; i < 10; i++) {
57 add_white(fuzz, atom);
58 }
59}
60
kjlubick5bd98a22016-02-18 06:27:38 -080061static void add_comma(Fuzz* fuzz, SkString* atom) {
62 if (gEasy) {
63 atom->append(",");
64 return;
65 }
kjlubick5bd98a22016-02-18 06:27:38 -080066 add_white(fuzz, atom);
Kevin Lubick416b2482016-11-10 16:17:49 -050067 bool b;
68 fuzz->next(&b);
69 if (b) {
kjlubick5bd98a22016-02-18 06:27:38 -080070 atom->append(",");
71 }
Kevin Lubick2f535ce2016-11-01 15:01:12 -040072 add_some_white(fuzz, atom);
kjlubick5bd98a22016-02-18 06:27:38 -080073}
74
75SkString MakeRandomParsePathPiece(Fuzz* fuzz) {
76 SkString atom;
Kevin Lubick416b2482016-11-10 16:17:49 -050077 uint8_t index;
Kevin Lubickc9f0cc82016-11-15 16:07:02 -050078 fuzz->nextRange(&index, 0, (int) SK_ARRAY_COUNT(gLegal) - 1);
kjlubick5bd98a22016-02-18 06:27:38 -080079 const Legal& legal = gLegal[index];
80 gEasy ? atom.append("\n") : add_white(fuzz, &atom);
Kevin Lubick416b2482016-11-10 16:17:49 -050081 bool b;
82 fuzz->next(&b);
83 char symbol = legal.fSymbol | (b ? 0x20 : 0);
kjlubick5bd98a22016-02-18 06:27:38 -080084 atom.append(&symbol, 1);
Kevin Lubick416b2482016-11-10 16:17:49 -050085 uint8_t reps;
86 fuzz->nextRange(&reps, 1, 3);
kjlubick5bd98a22016-02-18 06:27:38 -080087 for (int rep = 0; rep < reps; ++rep) {
88 for (int index = 0; index < legal.fScalars; ++index) {
Kevin Lubick416b2482016-11-10 16:17:49 -050089 SkScalar coord;
90 fuzz->nextRange(&coord, 0.0f, 100.0f);
kjlubick5bd98a22016-02-18 06:27:38 -080091 add_white(fuzz, &atom);
92 atom.appendScalar(coord);
93 if (rep < reps - 1 && index < legal.fScalars - 1) {
94 add_comma(fuzz, &atom);
95 } else {
96 add_some_white(fuzz, &atom);
97 }
98 if ('A' == legal.fSymbol && 1 == index) {
Kevin Lubick416b2482016-11-10 16:17:49 -050099 SkScalar s;
100 fuzz->nextRange(&s, -720.0f, 720.0f);
101 atom.appendScalar(s);
kjlubick5bd98a22016-02-18 06:27:38 -0800102 add_comma(fuzz, &atom);
Kevin Lubick416b2482016-11-10 16:17:49 -0500103 fuzz->next(&b);
104 atom.appendU32(b);
kjlubick5bd98a22016-02-18 06:27:38 -0800105 add_comma(fuzz, &atom);
Kevin Lubick416b2482016-11-10 16:17:49 -0500106 fuzz->next(&b);
107 atom.appendU32(b);
kjlubick5bd98a22016-02-18 06:27:38 -0800108 add_comma(fuzz, &atom);
109 }
110 }
111 }
112 return atom;
113}
114
115DEF_FUZZ(ParsePath, fuzz) {
116 SkPath path;
117 SkString spec;
Kevin Lubick416b2482016-11-10 16:17:49 -0500118 uint8_t count;
119 fuzz->nextRange(&count, 0, 40);
120 for (uint8_t i = 0; i < count; ++i) {
kjlubick5bd98a22016-02-18 06:27:38 -0800121 spec.append(MakeRandomParsePathPiece(fuzz));
122 }
123 SkDebugf("SkParsePath::FromSVGString(%s, &path);\n",spec.c_str());
124 if (!SkParsePath::FromSVGString(spec.c_str(), &path)){
Kevin Lubick2f535ce2016-11-01 15:01:12 -0400125 SkDebugf("Could not decode path\n");
kjlubick5bd98a22016-02-18 06:27:38 -0800126 }
127}