blob: a619465cafb5dd5e2f78b32d7904f5f450e6a6b8 [file] [log] [blame]
// Copyright 2019 Joe Drago. All rights reserved.
// SPDX-License-Identifier: BSD-2-Clause
#include "avif/avif.h"
#include "avif/avif_cxx.h"
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size) {
avif::DecoderPtr decoder(avifDecoderCreate());
if (decoder == nullptr) return 0;
decoder->allowProgressive = AVIF_TRUE;
// ClusterFuzz passes -rss_limit_mb=2560 to avif_decode_fuzzer. Empirically
// setting decoder->imageSizeLimit to this value allows avif_decode_fuzzer to
// consume no more than 2560 MB of memory. Also limit the dimensions to avoid
// timeouts and to speed the fuzzing up.
// avifDecoderParse returns AVIF_RESULT_NOT_IMPLEMENTED if kImageSizeLimit is
// bigger than AVIF_DEFAULT_IMAGE_SIZE_LIMIT.
constexpr uint32_t kImageSizeLimit = 4 * 1024 * 4 * 1024;
static_assert(kImageSizeLimit <= AVIF_DEFAULT_IMAGE_SIZE_LIMIT,
"Too big an image size limit");
decoder->imageSizeLimit = kImageSizeLimit;
avifIO* const io = avifIOCreateMemoryReader(Data, Size);
if (io == nullptr) return 0;
// Simulate Chrome's avifIO object, which is not persistent.
io->persistent = AVIF_FALSE;
avifDecoderSetIO(decoder.get(), io);
if (avifDecoderParse(decoder.get()) != AVIF_RESULT_OK) return 0;
while (avifDecoderNextImage(decoder.get()) == AVIF_RESULT_OK) {
}
// Loop once.
if (avifDecoderReset(decoder.get()) != AVIF_RESULT_OK) return 0;
while (avifDecoderNextImage(decoder.get()) == AVIF_RESULT_OK) {
}
return 0; // Non-zero return values are reserved for future use.
}