blob: c5004a2fe777ee5eee6601115f7067e78a2cba13 [file] [log] [blame]
Leon Scroggins III0b8fcbc2018-10-16 15:52:17 -04001/*
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 "SkBitmap.h"
9#include "SkCodec.h"
10#include "SkData.h"
11
12bool FuzzIncrementalImage(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#if defined(IS_FUZZING_WITH_LIBFUZZER)
49extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
50 auto bytes = SkData::MakeWithoutCopy(data, size);
51 FuzzIncrementalImage(bytes);
52 return 0;
53}
54#endif