1 /*
2  * Copyright 2018 Google, LLC
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 "include/codec/SkCodec.h"
9 #include "include/core/SkBitmap.h"
10 #include "include/core/SkData.h"
11 
FuzzIncrementalImageDecode(sk_sp<SkData> bytes)12 bool FuzzIncrementalImageDecode(sk_sp<SkData> bytes) {
13     auto codec = SkCodec::MakeFromData(bytes);
14     if (!codec) {
15         return false;
16     }
17 
18     SkBitmap bm;
19     if (!bm.tryAllocPixels(codec->getInfo())) {
20         // May fail in memory-constrained fuzzing environments
21         return false;
22     }
23 
24     auto result = codec->startIncrementalDecode(bm.info(), bm.getPixels(), bm.rowBytes());
25     if (result != SkCodec::kSuccess) {
26         return false;
27     }
28 
29     // Deliberately uninitialized to verify that incrementalDecode initializes it when it
30     // returns kIncompleteInput or kErrorInInput.
31     int rowsDecoded;
32     result = codec->incrementalDecode(&rowsDecoded);
33     switch (result) {
34         case SkCodec::kIncompleteInput:
35         case SkCodec::kErrorInInput:
36             if (rowsDecoded < bm.height()) {
37                 void* dst = SkTAddOffset<void>(bm.getPixels(), rowsDecoded * bm.rowBytes());
38                 sk_bzero(dst, (bm.height() - rowsDecoded) * bm.rowBytes());
39             }
40             return true; // decoded a partial image
41          case SkCodec::kSuccess:
42             return true;
43          default:
44             return false;
45     }
46 }
47 
48 // TODO(kjlubick): remove IS_FUZZING... after https://crrev.com/c/2410304 lands
49 #if defined(SK_BUILD_FOR_LIBFUZZER) || defined(IS_FUZZING_WITH_LIBFUZZER)
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)50 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
51     if (size > 10240) {
52         return 0;
53     }
54     auto bytes = SkData::MakeWithoutCopy(data, size);
55     FuzzIncrementalImageDecode(bytes);
56     return 0;
57 }
58 #endif
59