1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2016 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker
8*c8dee2aaSAndroid Build Coastguard Worker #include "fuzz/Fuzz.h"
9*c8dee2aaSAndroid Build Coastguard Worker #include "include/codec/SkCodec.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkBitmap.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkCanvas.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkData.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkFontMgr.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkImage.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkMallocPixelRef.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPaint.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPath.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkStream.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSurface.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTextBlob.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "include/encode/SkPngEncoder.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkOSFile.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkReadBuffer.h"
24*c8dee2aaSAndroid Build Coastguard Worker #include "src/utils/SkOSPath.h"
25*c8dee2aaSAndroid Build Coastguard Worker #include "tools/ToolUtils.h"
26*c8dee2aaSAndroid Build Coastguard Worker #include "tools/flags/CommandLineFlags.h"
27*c8dee2aaSAndroid Build Coastguard Worker #include "tools/fonts/FontToolUtils.h"
28*c8dee2aaSAndroid Build Coastguard Worker
29*c8dee2aaSAndroid Build Coastguard Worker #include <iostream>
30*c8dee2aaSAndroid Build Coastguard Worker #include <map>
31*c8dee2aaSAndroid Build Coastguard Worker #include <regex>
32*c8dee2aaSAndroid Build Coastguard Worker #include <signal.h>
33*c8dee2aaSAndroid Build Coastguard Worker
34*c8dee2aaSAndroid Build Coastguard Worker static DEFINE_string2(bytes, b, "", "A path to a file or a directory. If a file, the "
35*c8dee2aaSAndroid Build Coastguard Worker "contents will be used as the fuzz bytes. If a directory, all files "
36*c8dee2aaSAndroid Build Coastguard Worker "in the directory will be used as fuzz bytes for the fuzzer, one at a "
37*c8dee2aaSAndroid Build Coastguard Worker "time.");
38*c8dee2aaSAndroid Build Coastguard Worker static DEFINE_string2(name, n, "", "If --type is 'api', fuzz the API with this name.");
39*c8dee2aaSAndroid Build Coastguard Worker static DEFINE_string2(dump, d, "", "If not empty, dump 'image*' or 'skp' types as a "
40*c8dee2aaSAndroid Build Coastguard Worker "PNG with this name.");
41*c8dee2aaSAndroid Build Coastguard Worker static DEFINE_int(loops, 1, "Run the fuzzer on each input this many times.");
42*c8dee2aaSAndroid Build Coastguard Worker DEFINE_bool2(verbose, v, false, "Print more information while fuzzing.");
43*c8dee2aaSAndroid Build Coastguard Worker
44*c8dee2aaSAndroid Build Coastguard Worker // This cannot be inlined in DEFINE_string2 due to interleaved ifdefs
45*c8dee2aaSAndroid Build Coastguard Worker static constexpr char g_type_message[] = "How to interpret --bytes, one of:\n"
46*c8dee2aaSAndroid Build Coastguard Worker "android_codec\n"
47*c8dee2aaSAndroid Build Coastguard Worker "animated_image_decode\n"
48*c8dee2aaSAndroid Build Coastguard Worker "api\n"
49*c8dee2aaSAndroid Build Coastguard Worker "color_deserialize\n"
50*c8dee2aaSAndroid Build Coastguard Worker "colrv1\n"
51*c8dee2aaSAndroid Build Coastguard Worker "filter_fuzz (equivalent to Chrome's filter_fuzz_stub)\n"
52*c8dee2aaSAndroid Build Coastguard Worker "image_decode\n"
53*c8dee2aaSAndroid Build Coastguard Worker "image_decode_incremental\n"
54*c8dee2aaSAndroid Build Coastguard Worker "image_mode\n"
55*c8dee2aaSAndroid Build Coastguard Worker "image_scale\n"
56*c8dee2aaSAndroid Build Coastguard Worker "json\n"
57*c8dee2aaSAndroid Build Coastguard Worker "path_deserialize\n"
58*c8dee2aaSAndroid Build Coastguard Worker "region_deserialize\n"
59*c8dee2aaSAndroid Build Coastguard Worker "region_set_path\n"
60*c8dee2aaSAndroid Build Coastguard Worker "skdescriptor_deserialize\n"
61*c8dee2aaSAndroid Build Coastguard Worker "skmeshspecialization\n"
62*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_ENABLE_SKOTTIE)
63*c8dee2aaSAndroid Build Coastguard Worker "skottie_json\n"
64*c8dee2aaSAndroid Build Coastguard Worker #endif
65*c8dee2aaSAndroid Build Coastguard Worker "skp\n"
66*c8dee2aaSAndroid Build Coastguard Worker "skruntimeblender\n"
67*c8dee2aaSAndroid Build Coastguard Worker "skruntimecolorfilter\n"
68*c8dee2aaSAndroid Build Coastguard Worker "skruntimeeffect\n"
69*c8dee2aaSAndroid Build Coastguard Worker "sksl2glsl\n"
70*c8dee2aaSAndroid Build Coastguard Worker "sksl2metal\n"
71*c8dee2aaSAndroid Build Coastguard Worker "sksl2pipeline\n"
72*c8dee2aaSAndroid Build Coastguard Worker "sksl2spirv\n"
73*c8dee2aaSAndroid Build Coastguard Worker "sksl2wgsl\n"
74*c8dee2aaSAndroid Build Coastguard Worker "svg_dom\n"
75*c8dee2aaSAndroid Build Coastguard Worker "textblob";
76*c8dee2aaSAndroid Build Coastguard Worker
77*c8dee2aaSAndroid Build Coastguard Worker static DEFINE_string2(type, t, "", g_type_message);
78*c8dee2aaSAndroid Build Coastguard Worker
79*c8dee2aaSAndroid Build Coastguard Worker static int fuzz_file(const SkString& path, SkString type);
80*c8dee2aaSAndroid Build Coastguard Worker static uint8_t calculate_option(SkData*);
81*c8dee2aaSAndroid Build Coastguard Worker static SkString try_auto_detect(const SkString& path, SkString* name);
82*c8dee2aaSAndroid Build Coastguard Worker
83*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_android_codec(const sk_sp<SkData>&);
84*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_animated_img(const sk_sp<SkData>&);
85*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_api(const sk_sp<SkData>&, const SkString& name);
86*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_color_deserialize(const sk_sp<SkData>&);
87*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_colrv1(const sk_sp<SkData>&);
88*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_filter_fuzz(const sk_sp<SkData>&);
89*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_image_decode(const sk_sp<SkData>&);
90*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_image_decode_incremental(const sk_sp<SkData>&);
91*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_img(const sk_sp<SkData>&, uint8_t, uint8_t);
92*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_json(const sk_sp<SkData>&);
93*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_parse_path(const sk_sp<SkData>&);
94*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_path_deserialize(const sk_sp<SkData>&);
95*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_region_deserialize(const sk_sp<SkData>&);
96*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_region_set_path(const sk_sp<SkData>&);
97*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_skdescriptor_deserialize(const sk_sp<SkData>&);
98*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_skmeshspecification(const sk_sp<SkData>&);
99*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_skp(const sk_sp<SkData>&);
100*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_skruntimeblender(const sk_sp<SkData>&);
101*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_skruntimecolorfilter(const sk_sp<SkData>&);
102*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_skruntimeeffect(const sk_sp<SkData>&);
103*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_sksl2glsl(const sk_sp<SkData>&);
104*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_sksl2metal(const sk_sp<SkData>&);
105*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_sksl2pipeline(const sk_sp<SkData>&);
106*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_sksl2spirv(const sk_sp<SkData>&);
107*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_sksl2wgsl(const sk_sp<SkData>&);
108*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_textblob_deserialize(const sk_sp<SkData>&);
109*c8dee2aaSAndroid Build Coastguard Worker
110*c8dee2aaSAndroid Build Coastguard Worker static void print_api_names();
111*c8dee2aaSAndroid Build Coastguard Worker
112*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_ENABLE_SVG)
113*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_svg_dom(const sk_sp<SkData>&);
114*c8dee2aaSAndroid Build Coastguard Worker #endif
115*c8dee2aaSAndroid Build Coastguard Worker
116*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_ENABLE_SKOTTIE)
117*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_skottie_json(const sk_sp<SkData>&);
118*c8dee2aaSAndroid Build Coastguard Worker #endif
119*c8dee2aaSAndroid Build Coastguard Worker
main(int argc,char ** argv)120*c8dee2aaSAndroid Build Coastguard Worker int main(int argc, char** argv) {
121*c8dee2aaSAndroid Build Coastguard Worker CommandLineFlags::SetUsage(
122*c8dee2aaSAndroid Build Coastguard Worker "Usage: fuzz -t <type> -b <path/to/file> [-n api-to-fuzz]\n"
123*c8dee2aaSAndroid Build Coastguard Worker " fuzz -b <path/to/file>\n"
124*c8dee2aaSAndroid Build Coastguard Worker "--help lists the valid types. If type is not specified,\n"
125*c8dee2aaSAndroid Build Coastguard Worker "fuzz will make a guess based on the name of the file.\n");
126*c8dee2aaSAndroid Build Coastguard Worker CommandLineFlags::Parse(argc, argv);
127*c8dee2aaSAndroid Build Coastguard Worker ToolUtils::UsePortableFontMgr();
128*c8dee2aaSAndroid Build Coastguard Worker
129*c8dee2aaSAndroid Build Coastguard Worker SkString path = SkString(FLAGS_bytes.isEmpty() ? argv[0] : FLAGS_bytes[0]);
130*c8dee2aaSAndroid Build Coastguard Worker SkString type = SkString(FLAGS_type.isEmpty() ? "" : FLAGS_type[0]);
131*c8dee2aaSAndroid Build Coastguard Worker
132*c8dee2aaSAndroid Build Coastguard Worker int loopCount = std::max(FLAGS_loops, 1);
133*c8dee2aaSAndroid Build Coastguard Worker
134*c8dee2aaSAndroid Build Coastguard Worker if (!sk_isdir(path.c_str())) {
135*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < loopCount; ++i) {
136*c8dee2aaSAndroid Build Coastguard Worker int rv = fuzz_file(path, type);
137*c8dee2aaSAndroid Build Coastguard Worker if (rv != 0) {
138*c8dee2aaSAndroid Build Coastguard Worker return rv;
139*c8dee2aaSAndroid Build Coastguard Worker }
140*c8dee2aaSAndroid Build Coastguard Worker }
141*c8dee2aaSAndroid Build Coastguard Worker return 0;
142*c8dee2aaSAndroid Build Coastguard Worker }
143*c8dee2aaSAndroid Build Coastguard Worker
144*c8dee2aaSAndroid Build Coastguard Worker SkOSFile::Iter it(path.c_str());
145*c8dee2aaSAndroid Build Coastguard Worker for (SkString file; it.next(&file); ) {
146*c8dee2aaSAndroid Build Coastguard Worker SkString p = SkOSPath::Join(path.c_str(), file.c_str());
147*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("Fuzzing %s\n", p.c_str());
148*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < loopCount; ++i) {
149*c8dee2aaSAndroid Build Coastguard Worker int rv = fuzz_file(p, type);
150*c8dee2aaSAndroid Build Coastguard Worker if (rv != 0) {
151*c8dee2aaSAndroid Build Coastguard Worker return rv;
152*c8dee2aaSAndroid Build Coastguard Worker }
153*c8dee2aaSAndroid Build Coastguard Worker }
154*c8dee2aaSAndroid Build Coastguard Worker }
155*c8dee2aaSAndroid Build Coastguard Worker return 0;
156*c8dee2aaSAndroid Build Coastguard Worker }
157*c8dee2aaSAndroid Build Coastguard Worker
fuzz_file(const SkString & path,SkString type)158*c8dee2aaSAndroid Build Coastguard Worker static int fuzz_file(const SkString& path, SkString type) {
159*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkData> bytes(SkData::MakeFromFileName(path.c_str()));
160*c8dee2aaSAndroid Build Coastguard Worker if (!bytes) {
161*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("Could not read %s\n", path.c_str());
162*c8dee2aaSAndroid Build Coastguard Worker return 1;
163*c8dee2aaSAndroid Build Coastguard Worker }
164*c8dee2aaSAndroid Build Coastguard Worker
165*c8dee2aaSAndroid Build Coastguard Worker SkString name = SkString(FLAGS_name.isEmpty() ? "" : FLAGS_name[0]);
166*c8dee2aaSAndroid Build Coastguard Worker
167*c8dee2aaSAndroid Build Coastguard Worker if (type.isEmpty()) {
168*c8dee2aaSAndroid Build Coastguard Worker type = try_auto_detect(path, &name);
169*c8dee2aaSAndroid Build Coastguard Worker }
170*c8dee2aaSAndroid Build Coastguard Worker
171*c8dee2aaSAndroid Build Coastguard Worker if (type.isEmpty()) {
172*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("Could not autodetect type of %s\n", path.c_str());
173*c8dee2aaSAndroid Build Coastguard Worker return 1;
174*c8dee2aaSAndroid Build Coastguard Worker }
175*c8dee2aaSAndroid Build Coastguard Worker if (type.equals("android_codec")) {
176*c8dee2aaSAndroid Build Coastguard Worker fuzz_android_codec(std::move(bytes));
177*c8dee2aaSAndroid Build Coastguard Worker return 0;
178*c8dee2aaSAndroid Build Coastguard Worker }
179*c8dee2aaSAndroid Build Coastguard Worker if (type.equals("animated_image_decode")) {
180*c8dee2aaSAndroid Build Coastguard Worker fuzz_animated_img(std::move(bytes));
181*c8dee2aaSAndroid Build Coastguard Worker return 0;
182*c8dee2aaSAndroid Build Coastguard Worker }
183*c8dee2aaSAndroid Build Coastguard Worker if (type.equals("api")) {
184*c8dee2aaSAndroid Build Coastguard Worker fuzz_api(bytes, name);
185*c8dee2aaSAndroid Build Coastguard Worker return 0;
186*c8dee2aaSAndroid Build Coastguard Worker }
187*c8dee2aaSAndroid Build Coastguard Worker if (type.equals("color_deserialize")) {
188*c8dee2aaSAndroid Build Coastguard Worker fuzz_color_deserialize(std::move(bytes));
189*c8dee2aaSAndroid Build Coastguard Worker return 0;
190*c8dee2aaSAndroid Build Coastguard Worker }
191*c8dee2aaSAndroid Build Coastguard Worker if (type.equals("colrv1")) {
192*c8dee2aaSAndroid Build Coastguard Worker fuzz_colrv1(std::move(bytes));
193*c8dee2aaSAndroid Build Coastguard Worker return 0;
194*c8dee2aaSAndroid Build Coastguard Worker }
195*c8dee2aaSAndroid Build Coastguard Worker if (type.equals("filter_fuzz")) {
196*c8dee2aaSAndroid Build Coastguard Worker fuzz_filter_fuzz(std::move(bytes));
197*c8dee2aaSAndroid Build Coastguard Worker return 0;
198*c8dee2aaSAndroid Build Coastguard Worker }
199*c8dee2aaSAndroid Build Coastguard Worker if (type.equals("image_decode")) {
200*c8dee2aaSAndroid Build Coastguard Worker fuzz_image_decode(std::move(bytes));
201*c8dee2aaSAndroid Build Coastguard Worker return 0;
202*c8dee2aaSAndroid Build Coastguard Worker }
203*c8dee2aaSAndroid Build Coastguard Worker if (type.equals("image_decode_incremental")) {
204*c8dee2aaSAndroid Build Coastguard Worker fuzz_image_decode_incremental(std::move(bytes));
205*c8dee2aaSAndroid Build Coastguard Worker return 0;
206*c8dee2aaSAndroid Build Coastguard Worker }
207*c8dee2aaSAndroid Build Coastguard Worker if (type.equals("image_scale")) {
208*c8dee2aaSAndroid Build Coastguard Worker uint8_t option = calculate_option(bytes.get());
209*c8dee2aaSAndroid Build Coastguard Worker fuzz_img(std::move(bytes), option, 0);
210*c8dee2aaSAndroid Build Coastguard Worker return 0;
211*c8dee2aaSAndroid Build Coastguard Worker }
212*c8dee2aaSAndroid Build Coastguard Worker if (type.equals("image_mode")) {
213*c8dee2aaSAndroid Build Coastguard Worker uint8_t option = calculate_option(bytes.get());
214*c8dee2aaSAndroid Build Coastguard Worker fuzz_img(std::move(bytes), 0, option);
215*c8dee2aaSAndroid Build Coastguard Worker return 0;
216*c8dee2aaSAndroid Build Coastguard Worker }
217*c8dee2aaSAndroid Build Coastguard Worker if (type.equals("json")) {
218*c8dee2aaSAndroid Build Coastguard Worker fuzz_json(std::move(bytes));
219*c8dee2aaSAndroid Build Coastguard Worker return 0;
220*c8dee2aaSAndroid Build Coastguard Worker }
221*c8dee2aaSAndroid Build Coastguard Worker if (type.equals("parse_path")) {
222*c8dee2aaSAndroid Build Coastguard Worker fuzz_parse_path(std::move(bytes));
223*c8dee2aaSAndroid Build Coastguard Worker return 0;
224*c8dee2aaSAndroid Build Coastguard Worker }
225*c8dee2aaSAndroid Build Coastguard Worker if (type.equals("path_deserialize")) {
226*c8dee2aaSAndroid Build Coastguard Worker fuzz_path_deserialize(std::move(bytes));
227*c8dee2aaSAndroid Build Coastguard Worker return 0;
228*c8dee2aaSAndroid Build Coastguard Worker }
229*c8dee2aaSAndroid Build Coastguard Worker if (type.equals("region_deserialize")) {
230*c8dee2aaSAndroid Build Coastguard Worker fuzz_region_deserialize(std::move(bytes));
231*c8dee2aaSAndroid Build Coastguard Worker return 0;
232*c8dee2aaSAndroid Build Coastguard Worker }
233*c8dee2aaSAndroid Build Coastguard Worker if (type.equals("region_set_path")) {
234*c8dee2aaSAndroid Build Coastguard Worker fuzz_region_set_path(std::move(bytes));
235*c8dee2aaSAndroid Build Coastguard Worker return 0;
236*c8dee2aaSAndroid Build Coastguard Worker }
237*c8dee2aaSAndroid Build Coastguard Worker if (type.equals("pipe")) {
238*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("I would prefer not to.\n");
239*c8dee2aaSAndroid Build Coastguard Worker return 0;
240*c8dee2aaSAndroid Build Coastguard Worker }
241*c8dee2aaSAndroid Build Coastguard Worker if (type.equals("skdescriptor_deserialize")) {
242*c8dee2aaSAndroid Build Coastguard Worker fuzz_skdescriptor_deserialize(std::move(bytes));
243*c8dee2aaSAndroid Build Coastguard Worker return 0;
244*c8dee2aaSAndroid Build Coastguard Worker }
245*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_ENABLE_SKOTTIE)
246*c8dee2aaSAndroid Build Coastguard Worker if (type.equals("skottie_json")) {
247*c8dee2aaSAndroid Build Coastguard Worker fuzz_skottie_json(std::move(bytes));
248*c8dee2aaSAndroid Build Coastguard Worker return 0;
249*c8dee2aaSAndroid Build Coastguard Worker }
250*c8dee2aaSAndroid Build Coastguard Worker #endif
251*c8dee2aaSAndroid Build Coastguard Worker if (type.equals("skmeshspecification")) {
252*c8dee2aaSAndroid Build Coastguard Worker fuzz_skmeshspecification(std::move(bytes));
253*c8dee2aaSAndroid Build Coastguard Worker return 0;
254*c8dee2aaSAndroid Build Coastguard Worker }
255*c8dee2aaSAndroid Build Coastguard Worker if (type.equals("skp")) {
256*c8dee2aaSAndroid Build Coastguard Worker fuzz_skp(std::move(bytes));
257*c8dee2aaSAndroid Build Coastguard Worker return 0;
258*c8dee2aaSAndroid Build Coastguard Worker }
259*c8dee2aaSAndroid Build Coastguard Worker if (type.equals("skruntimeblender")) {
260*c8dee2aaSAndroid Build Coastguard Worker fuzz_skruntimeblender(std::move(bytes));
261*c8dee2aaSAndroid Build Coastguard Worker return 0;
262*c8dee2aaSAndroid Build Coastguard Worker }
263*c8dee2aaSAndroid Build Coastguard Worker if (type.equals("skruntimecolorfilter")) {
264*c8dee2aaSAndroid Build Coastguard Worker fuzz_skruntimecolorfilter(std::move(bytes));
265*c8dee2aaSAndroid Build Coastguard Worker return 0;
266*c8dee2aaSAndroid Build Coastguard Worker }
267*c8dee2aaSAndroid Build Coastguard Worker if (type.equals("skruntimeeffect")) {
268*c8dee2aaSAndroid Build Coastguard Worker fuzz_skruntimeeffect(std::move(bytes));
269*c8dee2aaSAndroid Build Coastguard Worker return 0;
270*c8dee2aaSAndroid Build Coastguard Worker }
271*c8dee2aaSAndroid Build Coastguard Worker if (type.equals("sksl2glsl")) {
272*c8dee2aaSAndroid Build Coastguard Worker fuzz_sksl2glsl(std::move(bytes));
273*c8dee2aaSAndroid Build Coastguard Worker return 0;
274*c8dee2aaSAndroid Build Coastguard Worker }
275*c8dee2aaSAndroid Build Coastguard Worker if (type.equals("sksl2metal")) {
276*c8dee2aaSAndroid Build Coastguard Worker fuzz_sksl2metal(std::move(bytes));
277*c8dee2aaSAndroid Build Coastguard Worker return 0;
278*c8dee2aaSAndroid Build Coastguard Worker }
279*c8dee2aaSAndroid Build Coastguard Worker if (type.equals("sksl2pipeline")) {
280*c8dee2aaSAndroid Build Coastguard Worker fuzz_sksl2pipeline(std::move(bytes));
281*c8dee2aaSAndroid Build Coastguard Worker return 0;
282*c8dee2aaSAndroid Build Coastguard Worker }
283*c8dee2aaSAndroid Build Coastguard Worker if (type.equals("sksl2spirv")) {
284*c8dee2aaSAndroid Build Coastguard Worker fuzz_sksl2spirv(std::move(bytes));
285*c8dee2aaSAndroid Build Coastguard Worker return 0;
286*c8dee2aaSAndroid Build Coastguard Worker }
287*c8dee2aaSAndroid Build Coastguard Worker if (type.equals("sksl2wgsl")) {
288*c8dee2aaSAndroid Build Coastguard Worker fuzz_sksl2wgsl(std::move(bytes));
289*c8dee2aaSAndroid Build Coastguard Worker return 0;
290*c8dee2aaSAndroid Build Coastguard Worker }
291*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_ENABLE_SVG)
292*c8dee2aaSAndroid Build Coastguard Worker if (type.equals("svg_dom")) {
293*c8dee2aaSAndroid Build Coastguard Worker fuzz_svg_dom(std::move(bytes));
294*c8dee2aaSAndroid Build Coastguard Worker return 0;
295*c8dee2aaSAndroid Build Coastguard Worker }
296*c8dee2aaSAndroid Build Coastguard Worker #endif
297*c8dee2aaSAndroid Build Coastguard Worker if (type.equals("textblob")) {
298*c8dee2aaSAndroid Build Coastguard Worker fuzz_textblob_deserialize(std::move(bytes));
299*c8dee2aaSAndroid Build Coastguard Worker return 0;
300*c8dee2aaSAndroid Build Coastguard Worker }
301*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("Unknown type %s\n", type.c_str());
302*c8dee2aaSAndroid Build Coastguard Worker CommandLineFlags::PrintUsage();
303*c8dee2aaSAndroid Build Coastguard Worker return 1;
304*c8dee2aaSAndroid Build Coastguard Worker }
305*c8dee2aaSAndroid Build Coastguard Worker
306*c8dee2aaSAndroid Build Coastguard Worker static std::map<std::string, std::string> cf_api_map = {
307*c8dee2aaSAndroid Build Coastguard Worker {"api_create_ddl", "CreateDDL"},
308*c8dee2aaSAndroid Build Coastguard Worker {"api_draw_functions", "DrawFunctions"},
309*c8dee2aaSAndroid Build Coastguard Worker {"api_ddl_threading", "DDLThreadingGL"},
310*c8dee2aaSAndroid Build Coastguard Worker {"api_gradients", "Gradients"},
311*c8dee2aaSAndroid Build Coastguard Worker {"api_image_filter", "ImageFilter"},
312*c8dee2aaSAndroid Build Coastguard Worker {"api_mock_gpu_canvas", "MockGPUCanvas"},
313*c8dee2aaSAndroid Build Coastguard Worker {"api_null_canvas", "NullCanvas"},
314*c8dee2aaSAndroid Build Coastguard Worker {"api_path_measure", "PathMeasure"},
315*c8dee2aaSAndroid Build Coastguard Worker {"api_pathop", "Pathop"},
316*c8dee2aaSAndroid Build Coastguard Worker {"api_polyutils", "PolyUtils"},
317*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_GRAPHITE) && defined(SK_ENABLE_PRECOMPILE)
318*c8dee2aaSAndroid Build Coastguard Worker {"api_precompile", "Precompile"},
319*c8dee2aaSAndroid Build Coastguard Worker #endif
320*c8dee2aaSAndroid Build Coastguard Worker {"api_raster_n32_canvas", "RasterN32Canvas"},
321*c8dee2aaSAndroid Build Coastguard Worker {"api_skparagraph", "SkParagraph"},
322*c8dee2aaSAndroid Build Coastguard Worker {"api_svg_canvas", "SVGCanvas"},
323*c8dee2aaSAndroid Build Coastguard Worker {"cubic_quad_roots", "CubicQuadRoots"},
324*c8dee2aaSAndroid Build Coastguard Worker {"jpeg_encoder", "JPEGEncoder"},
325*c8dee2aaSAndroid Build Coastguard Worker {"png_encoder", "PNGEncoder"},
326*c8dee2aaSAndroid Build Coastguard Worker {"skia_pathop_fuzzer", "LegacyChromiumPathop"},
327*c8dee2aaSAndroid Build Coastguard Worker {"webp_encoder", "WEBPEncoder"}
328*c8dee2aaSAndroid Build Coastguard Worker };
329*c8dee2aaSAndroid Build Coastguard Worker
330*c8dee2aaSAndroid Build Coastguard Worker // maps clusterfuzz/oss-fuzz -> Skia's name
331*c8dee2aaSAndroid Build Coastguard Worker static std::map<std::string, std::string> cf_map = {
332*c8dee2aaSAndroid Build Coastguard Worker {"android_codec", "android_codec"},
333*c8dee2aaSAndroid Build Coastguard Worker {"animated_image_decode", "animated_image_decode"},
334*c8dee2aaSAndroid Build Coastguard Worker {"colrv1", "colrv1"},
335*c8dee2aaSAndroid Build Coastguard Worker {"image_decode", "image_decode"},
336*c8dee2aaSAndroid Build Coastguard Worker {"image_decode_incremental", "image_decode_incremental"},
337*c8dee2aaSAndroid Build Coastguard Worker {"image_filter_deserialize", "filter_fuzz"},
338*c8dee2aaSAndroid Build Coastguard Worker {"image_filter_deserialize_width", "filter_fuzz"},
339*c8dee2aaSAndroid Build Coastguard Worker {"path_deserialize", "path_deserialize"},
340*c8dee2aaSAndroid Build Coastguard Worker {"region_deserialize", "region_deserialize"},
341*c8dee2aaSAndroid Build Coastguard Worker {"region_set_path", "region_set_path"},
342*c8dee2aaSAndroid Build Coastguard Worker {"skdescriptor_deserialize", "skdescriptor_deserialize"},
343*c8dee2aaSAndroid Build Coastguard Worker {"skjson", "json"},
344*c8dee2aaSAndroid Build Coastguard Worker {"skmeshspecification", "skmeshspecification"},
345*c8dee2aaSAndroid Build Coastguard Worker {"skp", "skp"},
346*c8dee2aaSAndroid Build Coastguard Worker {"skruntimeeffect", "skruntimeeffect"},
347*c8dee2aaSAndroid Build Coastguard Worker {"sksl2glsl", "sksl2glsl"},
348*c8dee2aaSAndroid Build Coastguard Worker {"sksl2metal", "sksl2metal"},
349*c8dee2aaSAndroid Build Coastguard Worker {"sksl2spirv", "sksl2spirv"},
350*c8dee2aaSAndroid Build Coastguard Worker {"sksl2pipeline", "sksl2pipeline"},
351*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_ENABLE_SKOTTIE)
352*c8dee2aaSAndroid Build Coastguard Worker {"skottie_json", "skottie_json"},
353*c8dee2aaSAndroid Build Coastguard Worker #endif
354*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_ENABLE_SVG)
355*c8dee2aaSAndroid Build Coastguard Worker {"svg_dom", "svg_dom"},
356*c8dee2aaSAndroid Build Coastguard Worker #endif
357*c8dee2aaSAndroid Build Coastguard Worker {"textblob_deserialize", "textblob"}
358*c8dee2aaSAndroid Build Coastguard Worker };
359*c8dee2aaSAndroid Build Coastguard Worker
try_auto_detect(const SkString & path,SkString * name)360*c8dee2aaSAndroid Build Coastguard Worker static SkString try_auto_detect(const SkString& path, SkString* name) {
361*c8dee2aaSAndroid Build Coastguard Worker std::cmatch m;
362*c8dee2aaSAndroid Build Coastguard Worker std::regex clusterfuzz("clusterfuzz-testcase(-minimized)?-([a-z0-9_]+)-[\\d]+");
363*c8dee2aaSAndroid Build Coastguard Worker std::regex skiafuzzer("(api-)?(\\w+)-[a-f0-9]+");
364*c8dee2aaSAndroid Build Coastguard Worker
365*c8dee2aaSAndroid Build Coastguard Worker if (std::regex_search(path.c_str(), m, clusterfuzz)) {
366*c8dee2aaSAndroid Build Coastguard Worker std::string type = m.str(2);
367*c8dee2aaSAndroid Build Coastguard Worker
368*c8dee2aaSAndroid Build Coastguard Worker if (cf_api_map.find(type) != cf_api_map.end()) {
369*c8dee2aaSAndroid Build Coastguard Worker *name = SkString(cf_api_map[type].c_str());
370*c8dee2aaSAndroid Build Coastguard Worker return SkString("api");
371*c8dee2aaSAndroid Build Coastguard Worker } else {
372*c8dee2aaSAndroid Build Coastguard Worker if (cf_map.find(type) != cf_map.end()) {
373*c8dee2aaSAndroid Build Coastguard Worker return SkString(cf_map[type].c_str());
374*c8dee2aaSAndroid Build Coastguard Worker }
375*c8dee2aaSAndroid Build Coastguard Worker }
376*c8dee2aaSAndroid Build Coastguard Worker } else if (std::regex_search(path.c_str(), m, skiafuzzer)) {
377*c8dee2aaSAndroid Build Coastguard Worker std::string a1 = m.str(1);
378*c8dee2aaSAndroid Build Coastguard Worker std::string typeOrName = m.str(2);
379*c8dee2aaSAndroid Build Coastguard Worker if (a1.length() > 0) {
380*c8dee2aaSAndroid Build Coastguard Worker // it's an api fuzzer
381*c8dee2aaSAndroid Build Coastguard Worker *name = SkString(typeOrName.c_str());
382*c8dee2aaSAndroid Build Coastguard Worker return SkString("api");
383*c8dee2aaSAndroid Build Coastguard Worker } else {
384*c8dee2aaSAndroid Build Coastguard Worker return SkString(typeOrName.c_str());
385*c8dee2aaSAndroid Build Coastguard Worker }
386*c8dee2aaSAndroid Build Coastguard Worker }
387*c8dee2aaSAndroid Build Coastguard Worker
388*c8dee2aaSAndroid Build Coastguard Worker return SkString();
389*c8dee2aaSAndroid Build Coastguard Worker }
390*c8dee2aaSAndroid Build Coastguard Worker
391*c8dee2aaSAndroid Build Coastguard Worker void FuzzJSON(const uint8_t *data, size_t size);
392*c8dee2aaSAndroid Build Coastguard Worker
fuzz_json(const sk_sp<SkData> & data)393*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_json(const sk_sp<SkData>& data){
394*c8dee2aaSAndroid Build Coastguard Worker FuzzJSON(data->bytes(), data->size());
395*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Done parsing!\n");
396*c8dee2aaSAndroid Build Coastguard Worker }
397*c8dee2aaSAndroid Build Coastguard Worker
398*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_ENABLE_SKOTTIE)
399*c8dee2aaSAndroid Build Coastguard Worker void FuzzSkottieJSON(const uint8_t *data, size_t size);
400*c8dee2aaSAndroid Build Coastguard Worker
fuzz_skottie_json(const sk_sp<SkData> & data)401*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_skottie_json(const sk_sp<SkData>& data){
402*c8dee2aaSAndroid Build Coastguard Worker FuzzSkottieJSON(data->bytes(), data->size());
403*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Done animating!\n");
404*c8dee2aaSAndroid Build Coastguard Worker }
405*c8dee2aaSAndroid Build Coastguard Worker #endif
406*c8dee2aaSAndroid Build Coastguard Worker
407*c8dee2aaSAndroid Build Coastguard Worker #if defined(SK_ENABLE_SVG)
408*c8dee2aaSAndroid Build Coastguard Worker void FuzzSVG(const uint8_t *data, size_t size);
409*c8dee2aaSAndroid Build Coastguard Worker
fuzz_svg_dom(const sk_sp<SkData> & data)410*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_svg_dom(const sk_sp<SkData>& data){
411*c8dee2aaSAndroid Build Coastguard Worker FuzzSVG(data->bytes(), data->size());
412*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Done DOM!\n");
413*c8dee2aaSAndroid Build Coastguard Worker }
414*c8dee2aaSAndroid Build Coastguard Worker #endif
415*c8dee2aaSAndroid Build Coastguard Worker
416*c8dee2aaSAndroid Build Coastguard Worker void FuzzCOLRv1(const uint8_t* data, size_t size);
417*c8dee2aaSAndroid Build Coastguard Worker
fuzz_colrv1(const sk_sp<SkData> & data)418*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_colrv1(const sk_sp<SkData>& data) {
419*c8dee2aaSAndroid Build Coastguard Worker FuzzCOLRv1(data->bytes(), data->size());
420*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Done COLRv1!\n");
421*c8dee2aaSAndroid Build Coastguard Worker }
422*c8dee2aaSAndroid Build Coastguard Worker
423*c8dee2aaSAndroid Build Coastguard Worker // This adds up the first 1024 bytes and returns it as an 8 bit integer. This allows afl-fuzz to
424*c8dee2aaSAndroid Build Coastguard Worker // deterministically excercise different paths, or *options* (such as different scaling sizes or
425*c8dee2aaSAndroid Build Coastguard Worker // different image modes) without needing to introduce a parameter. This way we don't need a
426*c8dee2aaSAndroid Build Coastguard Worker // image_scale1, image_scale2, image_scale4, etc fuzzer, we can just have a image_scale fuzzer.
427*c8dee2aaSAndroid Build Coastguard Worker // Clients are expected to transform this number into a different range, e.g. with modulo (%).
calculate_option(SkData * bytes)428*c8dee2aaSAndroid Build Coastguard Worker static uint8_t calculate_option(SkData* bytes) {
429*c8dee2aaSAndroid Build Coastguard Worker uint8_t total = 0;
430*c8dee2aaSAndroid Build Coastguard Worker const uint8_t* data = bytes->bytes();
431*c8dee2aaSAndroid Build Coastguard Worker for (size_t i = 0; i < 1024 && i < bytes->size(); i++) {
432*c8dee2aaSAndroid Build Coastguard Worker total += data[i];
433*c8dee2aaSAndroid Build Coastguard Worker }
434*c8dee2aaSAndroid Build Coastguard Worker return total;
435*c8dee2aaSAndroid Build Coastguard Worker }
436*c8dee2aaSAndroid Build Coastguard Worker
print_api_names()437*c8dee2aaSAndroid Build Coastguard Worker static void print_api_names(){
438*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("When using --type api, please choose an API to fuzz with --name/-n:\n");
439*c8dee2aaSAndroid Build Coastguard Worker for (const Fuzzable& fuzzable : sk_tools::Registry<Fuzzable>::Range()) {
440*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("\t%s\n", fuzzable.name);
441*c8dee2aaSAndroid Build Coastguard Worker }
442*c8dee2aaSAndroid Build Coastguard Worker }
443*c8dee2aaSAndroid Build Coastguard Worker
fuzz_api(const sk_sp<SkData> & data,const SkString & name)444*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_api(const sk_sp<SkData>& data, const SkString& name) {
445*c8dee2aaSAndroid Build Coastguard Worker for (const Fuzzable& fuzzable : sk_tools::Registry<Fuzzable>::Range()) {
446*c8dee2aaSAndroid Build Coastguard Worker if (name.equals(fuzzable.name)) {
447*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("Fuzzing %s...\n", fuzzable.name);
448*c8dee2aaSAndroid Build Coastguard Worker Fuzz fuzz(data->bytes(), data->size());
449*c8dee2aaSAndroid Build Coastguard Worker fuzzable.fn(&fuzz);
450*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Success!\n");
451*c8dee2aaSAndroid Build Coastguard Worker return;
452*c8dee2aaSAndroid Build Coastguard Worker }
453*c8dee2aaSAndroid Build Coastguard Worker }
454*c8dee2aaSAndroid Build Coastguard Worker
455*c8dee2aaSAndroid Build Coastguard Worker print_api_names();
456*c8dee2aaSAndroid Build Coastguard Worker }
457*c8dee2aaSAndroid Build Coastguard Worker
dump_png(const SkBitmap & bitmap)458*c8dee2aaSAndroid Build Coastguard Worker static void dump_png(const SkBitmap& bitmap) {
459*c8dee2aaSAndroid Build Coastguard Worker if (!FLAGS_dump.isEmpty()) {
460*c8dee2aaSAndroid Build Coastguard Worker SkFILEWStream file(FLAGS_dump[0]);
461*c8dee2aaSAndroid Build Coastguard Worker SkPngEncoder::Encode(&file, bitmap.pixmap(), {});
462*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("Dumped to %s\n", FLAGS_dump[0]);
463*c8dee2aaSAndroid Build Coastguard Worker }
464*c8dee2aaSAndroid Build Coastguard Worker }
465*c8dee2aaSAndroid Build Coastguard Worker
466*c8dee2aaSAndroid Build Coastguard Worker bool FuzzAnimatedImage(const uint8_t *data, size_t size);
467*c8dee2aaSAndroid Build Coastguard Worker
fuzz_animated_img(const sk_sp<SkData> & data)468*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_animated_img(const sk_sp<SkData>& data) {
469*c8dee2aaSAndroid Build Coastguard Worker if (FuzzAnimatedImage(data->bytes(), data->size())) {
470*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Success from decoding/drawing animated image!\n");
471*c8dee2aaSAndroid Build Coastguard Worker return;
472*c8dee2aaSAndroid Build Coastguard Worker }
473*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Could not decode or draw animated image.\n");
474*c8dee2aaSAndroid Build Coastguard Worker }
475*c8dee2aaSAndroid Build Coastguard Worker
476*c8dee2aaSAndroid Build Coastguard Worker bool FuzzImageDecode(const uint8_t *data, size_t size);
477*c8dee2aaSAndroid Build Coastguard Worker
fuzz_image_decode(const sk_sp<SkData> & data)478*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_image_decode(const sk_sp<SkData>& data) {
479*c8dee2aaSAndroid Build Coastguard Worker if (FuzzImageDecode(data->bytes(), data->size())) {
480*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Success from decoding/drawing image!\n");
481*c8dee2aaSAndroid Build Coastguard Worker return;
482*c8dee2aaSAndroid Build Coastguard Worker }
483*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Could not decode or draw image.\n");
484*c8dee2aaSAndroid Build Coastguard Worker }
485*c8dee2aaSAndroid Build Coastguard Worker
486*c8dee2aaSAndroid Build Coastguard Worker bool FuzzIncrementalImageDecode(const uint8_t *data, size_t size);
487*c8dee2aaSAndroid Build Coastguard Worker
fuzz_image_decode_incremental(const sk_sp<SkData> & data)488*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_image_decode_incremental(const sk_sp<SkData>& data) {
489*c8dee2aaSAndroid Build Coastguard Worker if (FuzzIncrementalImageDecode(data->bytes(), data->size())) {
490*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Success using incremental decode!\n");
491*c8dee2aaSAndroid Build Coastguard Worker return;
492*c8dee2aaSAndroid Build Coastguard Worker }
493*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Could not incrementally decode and image.\n");
494*c8dee2aaSAndroid Build Coastguard Worker }
495*c8dee2aaSAndroid Build Coastguard Worker
496*c8dee2aaSAndroid Build Coastguard Worker bool FuzzAndroidCodec(const uint8_t *fuzzData, size_t fuzzSize, uint8_t sampleSize);
497*c8dee2aaSAndroid Build Coastguard Worker
fuzz_android_codec(const sk_sp<SkData> & data)498*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_android_codec(const sk_sp<SkData>& data) {
499*c8dee2aaSAndroid Build Coastguard Worker Fuzz fuzz(data->bytes(), data->size());
500*c8dee2aaSAndroid Build Coastguard Worker uint8_t sampleSize;
501*c8dee2aaSAndroid Build Coastguard Worker fuzz.nextRange(&sampleSize, 1, 64);
502*c8dee2aaSAndroid Build Coastguard Worker if (FuzzAndroidCodec(fuzz.remainingData(), fuzz.remainingSize(), sampleSize)) {
503*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Success on Android Codec sampleSize=%u!\n", sampleSize);
504*c8dee2aaSAndroid Build Coastguard Worker return;
505*c8dee2aaSAndroid Build Coastguard Worker }
506*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Could not use Android Codec sampleSize=%u!\n", sampleSize);
507*c8dee2aaSAndroid Build Coastguard Worker }
508*c8dee2aaSAndroid Build Coastguard Worker
509*c8dee2aaSAndroid Build Coastguard Worker // This is a "legacy" fuzzer that likely does too much. It was based off of how
510*c8dee2aaSAndroid Build Coastguard Worker // DM reads in images. image_decode, image_decode_incremental and android_codec
511*c8dee2aaSAndroid Build Coastguard Worker // are more targeted fuzzers that do a subset of what this one does.
fuzz_img(const sk_sp<SkData> & bytes,uint8_t scale,uint8_t mode)512*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_img(const sk_sp<SkData>& bytes, uint8_t scale, uint8_t mode) {
513*c8dee2aaSAndroid Build Coastguard Worker // We can scale 1x, 2x, 4x, 8x, 16x
514*c8dee2aaSAndroid Build Coastguard Worker scale = scale % 5;
515*c8dee2aaSAndroid Build Coastguard Worker float fscale = (float)pow(2.0f, scale);
516*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("Scaling factor: %f\n", fscale);
517*c8dee2aaSAndroid Build Coastguard Worker
518*c8dee2aaSAndroid Build Coastguard Worker // We have 5 different modes of decoding.
519*c8dee2aaSAndroid Build Coastguard Worker mode = mode % 5;
520*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("Mode: %d\n", mode);
521*c8dee2aaSAndroid Build Coastguard Worker
522*c8dee2aaSAndroid Build Coastguard Worker // This is mostly copied from DMSrcSink's CodecSrc::draw method.
523*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("Decoding\n");
524*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkCodec> codec(SkCodec::MakeFromData(bytes));
525*c8dee2aaSAndroid Build Coastguard Worker if (nullptr == codec) {
526*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Couldn't create codec.\n");
527*c8dee2aaSAndroid Build Coastguard Worker return;
528*c8dee2aaSAndroid Build Coastguard Worker }
529*c8dee2aaSAndroid Build Coastguard Worker
530*c8dee2aaSAndroid Build Coastguard Worker SkImageInfo decodeInfo = codec->getInfo();
531*c8dee2aaSAndroid Build Coastguard Worker SkISize size = codec->getScaledDimensions(fscale);
532*c8dee2aaSAndroid Build Coastguard Worker decodeInfo = decodeInfo.makeDimensions(size);
533*c8dee2aaSAndroid Build Coastguard Worker
534*c8dee2aaSAndroid Build Coastguard Worker SkBitmap bitmap;
535*c8dee2aaSAndroid Build Coastguard Worker SkCodec::Options options;
536*c8dee2aaSAndroid Build Coastguard Worker options.fZeroInitialized = SkCodec::kYes_ZeroInitialized;
537*c8dee2aaSAndroid Build Coastguard Worker
538*c8dee2aaSAndroid Build Coastguard Worker if (!bitmap.tryAllocPixelsFlags(decodeInfo, SkBitmap::kZeroPixels_AllocFlag)) {
539*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Could not allocate memory. Image might be too large (%d x %d)",
540*c8dee2aaSAndroid Build Coastguard Worker decodeInfo.width(), decodeInfo.height());
541*c8dee2aaSAndroid Build Coastguard Worker return;
542*c8dee2aaSAndroid Build Coastguard Worker }
543*c8dee2aaSAndroid Build Coastguard Worker
544*c8dee2aaSAndroid Build Coastguard Worker switch (mode) {
545*c8dee2aaSAndroid Build Coastguard Worker case 0: {//kCodecZeroInit_Mode, kCodec_Mode
546*c8dee2aaSAndroid Build Coastguard Worker switch (codec->getPixels(decodeInfo, bitmap.getPixels(), bitmap.rowBytes(), &options)) {
547*c8dee2aaSAndroid Build Coastguard Worker case SkCodec::kSuccess:
548*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Success!\n");
549*c8dee2aaSAndroid Build Coastguard Worker break;
550*c8dee2aaSAndroid Build Coastguard Worker case SkCodec::kIncompleteInput:
551*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Partial Success\n");
552*c8dee2aaSAndroid Build Coastguard Worker break;
553*c8dee2aaSAndroid Build Coastguard Worker case SkCodec::kErrorInInput:
554*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Partial Success with error\n");
555*c8dee2aaSAndroid Build Coastguard Worker break;
556*c8dee2aaSAndroid Build Coastguard Worker case SkCodec::kInvalidConversion:
557*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("Incompatible colortype conversion\n");
558*c8dee2aaSAndroid Build Coastguard Worker // Crash to allow afl-fuzz to know this was a bug.
559*c8dee2aaSAndroid Build Coastguard Worker raise(SIGSEGV);
560*c8dee2aaSAndroid Build Coastguard Worker break;
561*c8dee2aaSAndroid Build Coastguard Worker default:
562*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Couldn't getPixels.\n");
563*c8dee2aaSAndroid Build Coastguard Worker return;
564*c8dee2aaSAndroid Build Coastguard Worker }
565*c8dee2aaSAndroid Build Coastguard Worker break;
566*c8dee2aaSAndroid Build Coastguard Worker }
567*c8dee2aaSAndroid Build Coastguard Worker case 1: {//kScanline_Mode
568*c8dee2aaSAndroid Build Coastguard Worker if (SkCodec::kSuccess != codec->startScanlineDecode(decodeInfo)) {
569*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Could not start scanline decoder\n");
570*c8dee2aaSAndroid Build Coastguard Worker return;
571*c8dee2aaSAndroid Build Coastguard Worker }
572*c8dee2aaSAndroid Build Coastguard Worker
573*c8dee2aaSAndroid Build Coastguard Worker void* dst = bitmap.getAddr(0, 0);
574*c8dee2aaSAndroid Build Coastguard Worker size_t rowBytes = bitmap.rowBytes();
575*c8dee2aaSAndroid Build Coastguard Worker uint32_t height = decodeInfo.height();
576*c8dee2aaSAndroid Build Coastguard Worker // We do not need to check the return value. On an incomplete
577*c8dee2aaSAndroid Build Coastguard Worker // image, memory will be filled with a default value.
578*c8dee2aaSAndroid Build Coastguard Worker codec->getScanlines(dst, height, rowBytes);
579*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Success!\n");
580*c8dee2aaSAndroid Build Coastguard Worker break;
581*c8dee2aaSAndroid Build Coastguard Worker }
582*c8dee2aaSAndroid Build Coastguard Worker case 2: { //kStripe_Mode
583*c8dee2aaSAndroid Build Coastguard Worker const int height = decodeInfo.height();
584*c8dee2aaSAndroid Build Coastguard Worker // This value is chosen arbitrarily. We exercise more cases by choosing a value that
585*c8dee2aaSAndroid Build Coastguard Worker // does not align with image blocks.
586*c8dee2aaSAndroid Build Coastguard Worker const int stripeHeight = 37;
587*c8dee2aaSAndroid Build Coastguard Worker const int numStripes = (height + stripeHeight - 1) / stripeHeight;
588*c8dee2aaSAndroid Build Coastguard Worker
589*c8dee2aaSAndroid Build Coastguard Worker // Decode odd stripes
590*c8dee2aaSAndroid Build Coastguard Worker if (SkCodec::kSuccess != codec->startScanlineDecode(decodeInfo)
591*c8dee2aaSAndroid Build Coastguard Worker || SkCodec::kTopDown_SkScanlineOrder != codec->getScanlineOrder()) {
592*c8dee2aaSAndroid Build Coastguard Worker // This mode was designed to test the new skip scanlines API in libjpeg-turbo.
593*c8dee2aaSAndroid Build Coastguard Worker // Jpegs have kTopDown_SkScanlineOrder, and at this time, it is not interesting
594*c8dee2aaSAndroid Build Coastguard Worker // to run this test for image types that do not have this scanline ordering.
595*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Could not start top-down scanline decoder\n");
596*c8dee2aaSAndroid Build Coastguard Worker return;
597*c8dee2aaSAndroid Build Coastguard Worker }
598*c8dee2aaSAndroid Build Coastguard Worker
599*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < numStripes; i += 2) {
600*c8dee2aaSAndroid Build Coastguard Worker // Skip a stripe
601*c8dee2aaSAndroid Build Coastguard Worker const int linesToSkip = std::min(stripeHeight, height - i * stripeHeight);
602*c8dee2aaSAndroid Build Coastguard Worker codec->skipScanlines(linesToSkip);
603*c8dee2aaSAndroid Build Coastguard Worker
604*c8dee2aaSAndroid Build Coastguard Worker // Read a stripe
605*c8dee2aaSAndroid Build Coastguard Worker const int startY = (i + 1) * stripeHeight;
606*c8dee2aaSAndroid Build Coastguard Worker const int linesToRead = std::min(stripeHeight, height - startY);
607*c8dee2aaSAndroid Build Coastguard Worker if (linesToRead > 0) {
608*c8dee2aaSAndroid Build Coastguard Worker codec->getScanlines(bitmap.getAddr(0, startY), linesToRead, bitmap.rowBytes());
609*c8dee2aaSAndroid Build Coastguard Worker }
610*c8dee2aaSAndroid Build Coastguard Worker }
611*c8dee2aaSAndroid Build Coastguard Worker
612*c8dee2aaSAndroid Build Coastguard Worker // Decode even stripes
613*c8dee2aaSAndroid Build Coastguard Worker const SkCodec::Result startResult = codec->startScanlineDecode(decodeInfo);
614*c8dee2aaSAndroid Build Coastguard Worker if (SkCodec::kSuccess != startResult) {
615*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Failed to restart scanline decoder with same parameters.\n");
616*c8dee2aaSAndroid Build Coastguard Worker return;
617*c8dee2aaSAndroid Build Coastguard Worker }
618*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < numStripes; i += 2) {
619*c8dee2aaSAndroid Build Coastguard Worker // Read a stripe
620*c8dee2aaSAndroid Build Coastguard Worker const int startY = i * stripeHeight;
621*c8dee2aaSAndroid Build Coastguard Worker const int linesToRead = std::min(stripeHeight, height - startY);
622*c8dee2aaSAndroid Build Coastguard Worker codec->getScanlines(bitmap.getAddr(0, startY), linesToRead, bitmap.rowBytes());
623*c8dee2aaSAndroid Build Coastguard Worker
624*c8dee2aaSAndroid Build Coastguard Worker // Skip a stripe
625*c8dee2aaSAndroid Build Coastguard Worker const int linesToSkip = std::min(stripeHeight, height - (i + 1) * stripeHeight);
626*c8dee2aaSAndroid Build Coastguard Worker if (linesToSkip > 0) {
627*c8dee2aaSAndroid Build Coastguard Worker codec->skipScanlines(linesToSkip);
628*c8dee2aaSAndroid Build Coastguard Worker }
629*c8dee2aaSAndroid Build Coastguard Worker }
630*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Success!\n");
631*c8dee2aaSAndroid Build Coastguard Worker break;
632*c8dee2aaSAndroid Build Coastguard Worker }
633*c8dee2aaSAndroid Build Coastguard Worker case 3: { //kSubset_Mode
634*c8dee2aaSAndroid Build Coastguard Worker // Arbitrarily choose a divisor.
635*c8dee2aaSAndroid Build Coastguard Worker int divisor = 2;
636*c8dee2aaSAndroid Build Coastguard Worker // Total width/height of the image.
637*c8dee2aaSAndroid Build Coastguard Worker const int W = codec->getInfo().width();
638*c8dee2aaSAndroid Build Coastguard Worker const int H = codec->getInfo().height();
639*c8dee2aaSAndroid Build Coastguard Worker if (divisor > W || divisor > H) {
640*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Cannot codec subset: divisor %d is too big "
641*c8dee2aaSAndroid Build Coastguard Worker "with dimensions (%d x %d)\n", divisor, W, H);
642*c8dee2aaSAndroid Build Coastguard Worker return;
643*c8dee2aaSAndroid Build Coastguard Worker }
644*c8dee2aaSAndroid Build Coastguard Worker // subset dimensions
645*c8dee2aaSAndroid Build Coastguard Worker // SkWebpCodec, the only one that supports subsets, requires even top/left boundaries.
646*c8dee2aaSAndroid Build Coastguard Worker const int w = SkAlign2(W / divisor);
647*c8dee2aaSAndroid Build Coastguard Worker const int h = SkAlign2(H / divisor);
648*c8dee2aaSAndroid Build Coastguard Worker SkIRect subset;
649*c8dee2aaSAndroid Build Coastguard Worker SkCodec::Options opts;
650*c8dee2aaSAndroid Build Coastguard Worker opts.fSubset = ⊂
651*c8dee2aaSAndroid Build Coastguard Worker SkBitmap subsetBm;
652*c8dee2aaSAndroid Build Coastguard Worker // We will reuse pixel memory from bitmap.
653*c8dee2aaSAndroid Build Coastguard Worker void* pixels = bitmap.getPixels();
654*c8dee2aaSAndroid Build Coastguard Worker for (int x = 0; x < W; x += w) {
655*c8dee2aaSAndroid Build Coastguard Worker for (int y = 0; y < H; y+= h) {
656*c8dee2aaSAndroid Build Coastguard Worker // Do not make the subset go off the edge of the image.
657*c8dee2aaSAndroid Build Coastguard Worker const int preScaleW = std::min(w, W - x);
658*c8dee2aaSAndroid Build Coastguard Worker const int preScaleH = std::min(h, H - y);
659*c8dee2aaSAndroid Build Coastguard Worker subset.setXYWH(x, y, preScaleW, preScaleH);
660*c8dee2aaSAndroid Build Coastguard Worker // And fscale
661*c8dee2aaSAndroid Build Coastguard Worker // FIXME: Should we have a version of getScaledDimensions that takes a subset
662*c8dee2aaSAndroid Build Coastguard Worker // into account?
663*c8dee2aaSAndroid Build Coastguard Worker decodeInfo = decodeInfo.makeWH(
664*c8dee2aaSAndroid Build Coastguard Worker std::max(1, SkScalarRoundToInt(preScaleW * fscale)),
665*c8dee2aaSAndroid Build Coastguard Worker std::max(1, SkScalarRoundToInt(preScaleH * fscale)));
666*c8dee2aaSAndroid Build Coastguard Worker size_t rowBytes = decodeInfo.minRowBytes();
667*c8dee2aaSAndroid Build Coastguard Worker if (!subsetBm.installPixels(decodeInfo, pixels, rowBytes)) {
668*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Could not install pixels.\n");
669*c8dee2aaSAndroid Build Coastguard Worker return;
670*c8dee2aaSAndroid Build Coastguard Worker }
671*c8dee2aaSAndroid Build Coastguard Worker const SkCodec::Result result = codec->getPixels(decodeInfo, pixels, rowBytes,
672*c8dee2aaSAndroid Build Coastguard Worker &opts);
673*c8dee2aaSAndroid Build Coastguard Worker switch (result) {
674*c8dee2aaSAndroid Build Coastguard Worker case SkCodec::kSuccess:
675*c8dee2aaSAndroid Build Coastguard Worker case SkCodec::kIncompleteInput:
676*c8dee2aaSAndroid Build Coastguard Worker case SkCodec::kErrorInInput:
677*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("okay\n");
678*c8dee2aaSAndroid Build Coastguard Worker break;
679*c8dee2aaSAndroid Build Coastguard Worker case SkCodec::kInvalidConversion:
680*c8dee2aaSAndroid Build Coastguard Worker if (0 == (x|y)) {
681*c8dee2aaSAndroid Build Coastguard Worker // First subset is okay to return unimplemented.
682*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Incompatible colortype conversion\n");
683*c8dee2aaSAndroid Build Coastguard Worker return;
684*c8dee2aaSAndroid Build Coastguard Worker }
685*c8dee2aaSAndroid Build Coastguard Worker // If the first subset succeeded, a later one should not fail.
686*c8dee2aaSAndroid Build Coastguard Worker [[fallthrough]];
687*c8dee2aaSAndroid Build Coastguard Worker case SkCodec::kUnimplemented:
688*c8dee2aaSAndroid Build Coastguard Worker if (0 == (x|y)) {
689*c8dee2aaSAndroid Build Coastguard Worker // First subset is okay to return unimplemented.
690*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] subset codec not supported\n");
691*c8dee2aaSAndroid Build Coastguard Worker return;
692*c8dee2aaSAndroid Build Coastguard Worker }
693*c8dee2aaSAndroid Build Coastguard Worker // If the first subset succeeded, why would a later one fail?
694*c8dee2aaSAndroid Build Coastguard Worker [[fallthrough]];
695*c8dee2aaSAndroid Build Coastguard Worker default:
696*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] subset codec failed to decode (%d, %d, %d, %d) "
697*c8dee2aaSAndroid Build Coastguard Worker "with dimensions (%d x %d)\t error %d\n",
698*c8dee2aaSAndroid Build Coastguard Worker x, y, decodeInfo.width(), decodeInfo.height(),
699*c8dee2aaSAndroid Build Coastguard Worker W, H, result);
700*c8dee2aaSAndroid Build Coastguard Worker return;
701*c8dee2aaSAndroid Build Coastguard Worker }
702*c8dee2aaSAndroid Build Coastguard Worker }
703*c8dee2aaSAndroid Build Coastguard Worker }
704*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Success!\n");
705*c8dee2aaSAndroid Build Coastguard Worker break;
706*c8dee2aaSAndroid Build Coastguard Worker }
707*c8dee2aaSAndroid Build Coastguard Worker case 4: { //kAnimated_Mode
708*c8dee2aaSAndroid Build Coastguard Worker std::vector<SkCodec::FrameInfo> frameInfos = codec->getFrameInfo();
709*c8dee2aaSAndroid Build Coastguard Worker if (frameInfos.size() == 0) {
710*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Not an animated image\n");
711*c8dee2aaSAndroid Build Coastguard Worker break;
712*c8dee2aaSAndroid Build Coastguard Worker }
713*c8dee2aaSAndroid Build Coastguard Worker
714*c8dee2aaSAndroid Build Coastguard Worker for (size_t i = 0; i < frameInfos.size(); i++) {
715*c8dee2aaSAndroid Build Coastguard Worker options.fFrameIndex = i;
716*c8dee2aaSAndroid Build Coastguard Worker auto result = codec->startIncrementalDecode(decodeInfo, bitmap.getPixels(),
717*c8dee2aaSAndroid Build Coastguard Worker bitmap.rowBytes(), &options);
718*c8dee2aaSAndroid Build Coastguard Worker if (SkCodec::kSuccess != result) {
719*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] failed to start incremental decode "
720*c8dee2aaSAndroid Build Coastguard Worker "in frame %zu with error %d\n", i, result);
721*c8dee2aaSAndroid Build Coastguard Worker return;
722*c8dee2aaSAndroid Build Coastguard Worker }
723*c8dee2aaSAndroid Build Coastguard Worker
724*c8dee2aaSAndroid Build Coastguard Worker result = codec->incrementalDecode();
725*c8dee2aaSAndroid Build Coastguard Worker if (result == SkCodec::kIncompleteInput || result == SkCodec::kErrorInInput) {
726*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("okay\n");
727*c8dee2aaSAndroid Build Coastguard Worker // Frames beyond this one will not decode.
728*c8dee2aaSAndroid Build Coastguard Worker break;
729*c8dee2aaSAndroid Build Coastguard Worker }
730*c8dee2aaSAndroid Build Coastguard Worker if (result == SkCodec::kSuccess) {
731*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("okay - decoded frame %zu\n", i);
732*c8dee2aaSAndroid Build Coastguard Worker } else {
733*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] incremental decode failed with "
734*c8dee2aaSAndroid Build Coastguard Worker "error %d\n", result);
735*c8dee2aaSAndroid Build Coastguard Worker return;
736*c8dee2aaSAndroid Build Coastguard Worker }
737*c8dee2aaSAndroid Build Coastguard Worker }
738*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Success!\n");
739*c8dee2aaSAndroid Build Coastguard Worker break;
740*c8dee2aaSAndroid Build Coastguard Worker }
741*c8dee2aaSAndroid Build Coastguard Worker default:
742*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Mode not implemented yet\n");
743*c8dee2aaSAndroid Build Coastguard Worker }
744*c8dee2aaSAndroid Build Coastguard Worker
745*c8dee2aaSAndroid Build Coastguard Worker dump_png(bitmap);
746*c8dee2aaSAndroid Build Coastguard Worker }
747*c8dee2aaSAndroid Build Coastguard Worker
748*c8dee2aaSAndroid Build Coastguard Worker void FuzzSKP(const uint8_t *data, size_t size);
749*c8dee2aaSAndroid Build Coastguard Worker
fuzz_skp(const sk_sp<SkData> & data)750*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_skp(const sk_sp<SkData>& data) {
751*c8dee2aaSAndroid Build Coastguard Worker FuzzSKP(data->bytes(), data->size());
752*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Finished SKP\n");
753*c8dee2aaSAndroid Build Coastguard Worker }
754*c8dee2aaSAndroid Build Coastguard Worker
755*c8dee2aaSAndroid Build Coastguard Worker void FuzzColorspace(const uint8_t *data, size_t size);
756*c8dee2aaSAndroid Build Coastguard Worker
fuzz_color_deserialize(const sk_sp<SkData> & data)757*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_color_deserialize(const sk_sp<SkData>& data) {
758*c8dee2aaSAndroid Build Coastguard Worker FuzzColorspace(data->bytes(), data->size());
759*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Finished SkColorspace\n");
760*c8dee2aaSAndroid Build Coastguard Worker }
761*c8dee2aaSAndroid Build Coastguard Worker
762*c8dee2aaSAndroid Build Coastguard Worker void FuzzParsePath(const uint8_t *data, size_t size);
763*c8dee2aaSAndroid Build Coastguard Worker
fuzz_parse_path(const sk_sp<SkData> & data)764*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_parse_path(const sk_sp<SkData>& data) {
765*c8dee2aaSAndroid Build Coastguard Worker FuzzParsePath(data->bytes(), data->size());
766*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] parse_path didn't crash!\n");
767*c8dee2aaSAndroid Build Coastguard Worker }
768*c8dee2aaSAndroid Build Coastguard Worker
769*c8dee2aaSAndroid Build Coastguard Worker void FuzzPathDeserialize(const uint8_t *data, size_t size);
770*c8dee2aaSAndroid Build Coastguard Worker
fuzz_path_deserialize(const sk_sp<SkData> & data)771*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_path_deserialize(const sk_sp<SkData>& data) {
772*c8dee2aaSAndroid Build Coastguard Worker FuzzPathDeserialize(data->bytes(), data->size());
773*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] path_deserialize didn't crash!\n");
774*c8dee2aaSAndroid Build Coastguard Worker }
775*c8dee2aaSAndroid Build Coastguard Worker
776*c8dee2aaSAndroid Build Coastguard Worker bool FuzzRegionDeserialize(const uint8_t *data, size_t size);
777*c8dee2aaSAndroid Build Coastguard Worker
fuzz_region_deserialize(const sk_sp<SkData> & data)778*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_region_deserialize(const sk_sp<SkData>& data) {
779*c8dee2aaSAndroid Build Coastguard Worker if (!FuzzRegionDeserialize(data->bytes(), data->size())) {
780*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Couldn't initialize SkRegion.\n");
781*c8dee2aaSAndroid Build Coastguard Worker return;
782*c8dee2aaSAndroid Build Coastguard Worker }
783*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Success! Initialized SkRegion.\n");
784*c8dee2aaSAndroid Build Coastguard Worker }
785*c8dee2aaSAndroid Build Coastguard Worker
786*c8dee2aaSAndroid Build Coastguard Worker void FuzzTextBlobDeserialize(const uint8_t *data, size_t size);
787*c8dee2aaSAndroid Build Coastguard Worker
fuzz_textblob_deserialize(const sk_sp<SkData> & data)788*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_textblob_deserialize(const sk_sp<SkData>& data) {
789*c8dee2aaSAndroid Build Coastguard Worker FuzzTextBlobDeserialize(data->bytes(), data->size());
790*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] textblob didn't crash!\n");
791*c8dee2aaSAndroid Build Coastguard Worker }
792*c8dee2aaSAndroid Build Coastguard Worker
793*c8dee2aaSAndroid Build Coastguard Worker void FuzzRegionSetPath(Fuzz* fuzz);
794*c8dee2aaSAndroid Build Coastguard Worker
fuzz_region_set_path(const sk_sp<SkData> & data)795*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_region_set_path(const sk_sp<SkData>& data) {
796*c8dee2aaSAndroid Build Coastguard Worker Fuzz fuzz(data->bytes(), data->size());
797*c8dee2aaSAndroid Build Coastguard Worker FuzzRegionSetPath(&fuzz);
798*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] region_set_path didn't crash!\n");
799*c8dee2aaSAndroid Build Coastguard Worker }
800*c8dee2aaSAndroid Build Coastguard Worker
801*c8dee2aaSAndroid Build Coastguard Worker void FuzzImageFilterDeserialize(const uint8_t *data, size_t size);
802*c8dee2aaSAndroid Build Coastguard Worker
fuzz_filter_fuzz(const sk_sp<SkData> & data)803*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_filter_fuzz(const sk_sp<SkData>& data) {
804*c8dee2aaSAndroid Build Coastguard Worker FuzzImageFilterDeserialize(data->bytes(), data->size());
805*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] filter_fuzz didn't crash!\n");
806*c8dee2aaSAndroid Build Coastguard Worker }
807*c8dee2aaSAndroid Build Coastguard Worker
808*c8dee2aaSAndroid Build Coastguard Worker void FuzzSkMeshSpecification(const uint8_t *fuzzData, size_t fuzzSize);
809*c8dee2aaSAndroid Build Coastguard Worker
fuzz_skmeshspecification(const sk_sp<SkData> & data)810*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_skmeshspecification(const sk_sp<SkData>& data) {
811*c8dee2aaSAndroid Build Coastguard Worker FuzzSkMeshSpecification(data->bytes(), data->size());
812*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] SkMeshSpecification::Make didn't crash!\n");
813*c8dee2aaSAndroid Build Coastguard Worker }
814*c8dee2aaSAndroid Build Coastguard Worker
815*c8dee2aaSAndroid Build Coastguard Worker bool FuzzSkRuntimeBlender(const uint8_t *data, size_t size);
816*c8dee2aaSAndroid Build Coastguard Worker
fuzz_skruntimeblender(const sk_sp<SkData> & data)817*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_skruntimeblender(const sk_sp<SkData>& data) {
818*c8dee2aaSAndroid Build Coastguard Worker if (FuzzSkRuntimeBlender(data->bytes(), data->size())) {
819*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Success! Compiled and executed SkSL blender.\n");
820*c8dee2aaSAndroid Build Coastguard Worker } else {
821*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Could not compile or execute SkSL blender.\n");
822*c8dee2aaSAndroid Build Coastguard Worker }
823*c8dee2aaSAndroid Build Coastguard Worker }
824*c8dee2aaSAndroid Build Coastguard Worker
825*c8dee2aaSAndroid Build Coastguard Worker bool FuzzSkRuntimeColorFilter(const uint8_t *data, size_t size);
826*c8dee2aaSAndroid Build Coastguard Worker
fuzz_skruntimecolorfilter(const sk_sp<SkData> & data)827*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_skruntimecolorfilter(const sk_sp<SkData>& data) {
828*c8dee2aaSAndroid Build Coastguard Worker if (FuzzSkRuntimeColorFilter(data->bytes(), data->size())) {
829*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Success! Compiled and executed SkSL color filter.\n");
830*c8dee2aaSAndroid Build Coastguard Worker } else {
831*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Could not compile or execute SkSL color filter.\n");
832*c8dee2aaSAndroid Build Coastguard Worker }
833*c8dee2aaSAndroid Build Coastguard Worker }
834*c8dee2aaSAndroid Build Coastguard Worker
835*c8dee2aaSAndroid Build Coastguard Worker bool FuzzSkRuntimeEffect(const uint8_t *data, size_t size);
836*c8dee2aaSAndroid Build Coastguard Worker
fuzz_skruntimeeffect(const sk_sp<SkData> & data)837*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_skruntimeeffect(const sk_sp<SkData>& data) {
838*c8dee2aaSAndroid Build Coastguard Worker if (FuzzSkRuntimeEffect(data->bytes(), data->size())) {
839*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Success! Compiled and executed SkSL shader.\n");
840*c8dee2aaSAndroid Build Coastguard Worker } else {
841*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Could not compile or execute SkSL shader.\n");
842*c8dee2aaSAndroid Build Coastguard Worker }
843*c8dee2aaSAndroid Build Coastguard Worker }
844*c8dee2aaSAndroid Build Coastguard Worker
845*c8dee2aaSAndroid Build Coastguard Worker bool FuzzSKSL2GLSL(const uint8_t *data, size_t size);
846*c8dee2aaSAndroid Build Coastguard Worker
fuzz_sksl2glsl(const sk_sp<SkData> & data)847*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_sksl2glsl(const sk_sp<SkData>& data) {
848*c8dee2aaSAndroid Build Coastguard Worker if (FuzzSKSL2GLSL(data->bytes(), data->size())) {
849*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Success! Compiled input to GLSL.\n");
850*c8dee2aaSAndroid Build Coastguard Worker } else {
851*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Could not compile input to GLSL.\n");
852*c8dee2aaSAndroid Build Coastguard Worker }
853*c8dee2aaSAndroid Build Coastguard Worker }
854*c8dee2aaSAndroid Build Coastguard Worker
855*c8dee2aaSAndroid Build Coastguard Worker bool FuzzSKSL2Metal(const uint8_t *data, size_t size);
856*c8dee2aaSAndroid Build Coastguard Worker
fuzz_sksl2metal(const sk_sp<SkData> & data)857*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_sksl2metal(const sk_sp<SkData>& data) {
858*c8dee2aaSAndroid Build Coastguard Worker if (FuzzSKSL2Metal(data->bytes(), data->size())) {
859*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Success! Compiled input to Metal.\n");
860*c8dee2aaSAndroid Build Coastguard Worker } else {
861*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Could not compile input to Metal.\n");
862*c8dee2aaSAndroid Build Coastguard Worker }
863*c8dee2aaSAndroid Build Coastguard Worker }
864*c8dee2aaSAndroid Build Coastguard Worker
865*c8dee2aaSAndroid Build Coastguard Worker bool FuzzSKSL2Pipeline(const uint8_t *data, size_t size);
866*c8dee2aaSAndroid Build Coastguard Worker
fuzz_sksl2pipeline(const sk_sp<SkData> & data)867*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_sksl2pipeline(const sk_sp<SkData>& data) {
868*c8dee2aaSAndroid Build Coastguard Worker if (FuzzSKSL2Pipeline(data->bytes(), data->size())) {
869*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Success! Compiled input to pipeline stage.\n");
870*c8dee2aaSAndroid Build Coastguard Worker } else {
871*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Could not compile input to pipeline stage.\n");
872*c8dee2aaSAndroid Build Coastguard Worker }
873*c8dee2aaSAndroid Build Coastguard Worker }
874*c8dee2aaSAndroid Build Coastguard Worker
875*c8dee2aaSAndroid Build Coastguard Worker bool FuzzSKSL2SPIRV(const uint8_t *data, size_t size);
876*c8dee2aaSAndroid Build Coastguard Worker
fuzz_sksl2spirv(const sk_sp<SkData> & data)877*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_sksl2spirv(const sk_sp<SkData>& data) {
878*c8dee2aaSAndroid Build Coastguard Worker if (FuzzSKSL2SPIRV(data->bytes(), data->size())) {
879*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Success! Compiled input to SPIR-V.\n");
880*c8dee2aaSAndroid Build Coastguard Worker } else {
881*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Could not compile input to SPIR-V.\n");
882*c8dee2aaSAndroid Build Coastguard Worker }
883*c8dee2aaSAndroid Build Coastguard Worker }
884*c8dee2aaSAndroid Build Coastguard Worker
885*c8dee2aaSAndroid Build Coastguard Worker bool FuzzSKSL2WGSL(const uint8_t *data, size_t size);
886*c8dee2aaSAndroid Build Coastguard Worker
fuzz_sksl2wgsl(const sk_sp<SkData> & data)887*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_sksl2wgsl(const sk_sp<SkData>& data) {
888*c8dee2aaSAndroid Build Coastguard Worker if (FuzzSKSL2WGSL(data->bytes(), data->size())) {
889*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Success! Compiled input to WGSL.\n");
890*c8dee2aaSAndroid Build Coastguard Worker } else {
891*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Could not compile input to WGSL.\n");
892*c8dee2aaSAndroid Build Coastguard Worker }
893*c8dee2aaSAndroid Build Coastguard Worker }
894*c8dee2aaSAndroid Build Coastguard Worker
895*c8dee2aaSAndroid Build Coastguard Worker void FuzzSkDescriptorDeserialize(const uint8_t *data, size_t size);
896*c8dee2aaSAndroid Build Coastguard Worker
fuzz_skdescriptor_deserialize(const sk_sp<SkData> & data)897*c8dee2aaSAndroid Build Coastguard Worker static void fuzz_skdescriptor_deserialize(const sk_sp<SkData>& data) {
898*c8dee2aaSAndroid Build Coastguard Worker FuzzSkDescriptorDeserialize(data->bytes(), data->size());
899*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("[terminated] Did not crash while deserializing an SkDescriptor.\n");
900*c8dee2aaSAndroid Build Coastguard Worker }
901