skia2/fuzz/oss_fuzz/FuzzAndroidCodec.cpp
Leon Scroggins III 0b8fcbcfa3 Add fuzzers for SkAndroidCodec & incrementalDecode
Fuzz SkAndroidCodec to help to catch errors in both incrementalDecode
and scanlineDecode. Try a variety of sample sizes, but cap it at 64.
Though sometimes larger sample sizes are used, the lower ones tend to
more common. Also draw the resulting bitmap to verify that we
initialized all pixels.

Independently test incrementalDecode to ensure that it initializes
rowsDecoded.

Change-Id: I20d8a408cd280262fdc62f902a6f04f0f57f5ad2
Reviewed-on: https://skia-review.googlesource.com/c/162025
Commit-Queue: Kevin Lubick <kjlubick@google.com>
Auto-Submit: Leon Scroggins <scroggo@google.com>
Reviewed-by: Kevin Lubick <kjlubick@google.com>
2018-10-17 12:08:18 +00:00

64 lines
1.7 KiB
C++

/*
* Copyright 2018 Google, LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "SkAndroidCodec.h"
#include "SkBitmap.h"
#include "SkCanvas.h"
#include "SkData.h"
#include "SkSurface.h"
#include "../Fuzz.h"
bool FuzzAndroidCodec(sk_sp<SkData> bytes, uint8_t sampleSize) {
auto codec = SkAndroidCodec::MakeFromData(bytes);
if (!codec) {
return false;
}
auto size = codec->getSampledDimensions(sampleSize);
auto info = SkImageInfo::MakeN32Premul(size);
SkBitmap bm;
if (!bm.tryAllocPixels(info)) {
// May fail in memory-constrained fuzzing environments
return false;
}
SkAndroidCodec::AndroidOptions options;
options.fSampleSize = sampleSize;
auto result = codec->getAndroidPixels(bm.info(), bm.getPixels(), bm.rowBytes(), &options);
switch (result) {
case SkCodec::kSuccess:
case SkCodec::kIncompleteInput:
case SkCodec::kErrorInInput:
break;
default:
return false;
}
auto surface = SkSurface::MakeRasterN32Premul(size.width(), size.height());
if (!surface) {
// May return nullptr in memory-constrained fuzzing environments
return false;
}
surface->getCanvas()->drawBitmap(bm, 0, 0);
return true;
}
#if defined(IS_FUZZING_WITH_LIBFUZZER)
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
auto bytes = SkData::MakeWithoutCopy(data, size);
Fuzz fuzz(bytes);
uint8_t sampleSize;
fuzz.nextRange(&sampleSize, 1, 64);
bytes = SkData::MakeSubset(bytes.get(), 1, size - 1);
FuzzAndroidCodec(bytes, sampleSize);
return 0;
}
#endif