#include <cstddef>
#include <cstdint>
#include <string_view>
#include "./fuzz_utils.h"
#include "./nalloc.h"
#include "imageio/imageio_util.h"
#include "webp/decode.h"
#include "webp/demux.h"
#include "webp/mux_types.h"
namespace {
void AnimDecoderTest(std::string_view blob) {
const uint8_t* const data = reinterpret_cast<const uint8_t*>(blob.data());
const size_t size = blob.size();
nalloc_init(nullptr);
nalloc_start(data, size);
const size_t kMaxNumBytes = 2684354560; const size_t kMaxNumPixels = kMaxNumBytes / 4; const size_t kMaxNumPixelsSafe = kMaxNumPixels / 2; WebPBitstreamFeatures features;
if (WebPGetFeatures(data, size, &features) == VP8_STATUS_OK) {
if (!ImgIoUtilCheckSizeArgumentsOverflow(features.width * 4,
features.height) ||
static_cast<size_t>(features.width) * features.height >
kMaxNumPixelsSafe) {
nalloc_end();
return;
}
}
WebPData webp_data = {data, size};
WebPAnimDecoder* const dec = WebPAnimDecoderNew(&webp_data, nullptr);
if (dec == nullptr) {
nalloc_end();
return;
}
WebPAnimInfo info;
if (!WebPAnimDecoderGetInfo(dec, &info)) goto End;
if (!ImgIoUtilCheckSizeArgumentsOverflow(info.canvas_width * 4,
info.canvas_height)) {
goto End;
}
while (WebPAnimDecoderHasMoreFrames(dec)) {
uint8_t* buf;
int timestamp;
if (!WebPAnimDecoderGetNext(dec, &buf, ×tamp)) break;
}
End:
WebPAnimDecoderDelete(dec);
nalloc_end();
}
}
FUZZ_TEST(AnimDecoder, AnimDecoderTest)
.WithDomains(fuzztest::String().WithMaxSize(fuzz_utils::kMaxWebPFileSize +
1));