libwebp/tests/fuzzer/mux_demux_api_fuzzer.cc

110 lines
3.2 KiB
C++
Raw Normal View History

// Copyright 2018 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
#include <cstddef>
#include <cstdint>
#include <string_view>
#include "./fuzz_utils.h"
#include "src/webp/demux.h"
#include "src/webp/mux.h"
namespace {
void MuxDemuxApiTest(std::string_view data_in, bool mux) {
const size_t size = data_in.size();
WebPData webp_data;
WebPDataInit(&webp_data);
webp_data.size = size;
webp_data.bytes = reinterpret_cast<const uint8_t*>(data_in.data());
// Extracted chunks and frames are not processed or decoded,
// which is already covered extensively by the other fuzz targets.
if (mux) {
// Mux API
WebPMux* mux = WebPMuxCreate(&webp_data, size & 2);
if (!mux) return;
WebPData chunk;
(void)WebPMuxGetChunk(mux, "EXIF", &chunk);
(void)WebPMuxGetChunk(mux, "ICCP", &chunk);
(void)WebPMuxGetChunk(mux, "FUZZ", &chunk); // unknown
uint32_t flags;
(void)WebPMuxGetFeatures(mux, &flags);
WebPMuxAnimParams params;
(void)WebPMuxGetAnimationParams(mux, &params);
WebPMuxError status;
WebPMuxFrameInfo info;
for (int i = 0; i < fuzz_utils::kFuzzFrameLimit; i++) {
status = WebPMuxGetFrame(mux, i + 1, &info);
if (status == WEBP_MUX_NOT_FOUND) {
break;
} else if (status == WEBP_MUX_OK) {
WebPDataClear(&info.bitstream);
}
}
WebPMuxDelete(mux);
} else {
// Demux API
WebPDemuxer* demux;
if (size & 2) {
WebPDemuxState state;
demux = WebPDemuxPartial(&webp_data, &state);
if (state < WEBP_DEMUX_PARSED_HEADER) {
WebPDemuxDelete(demux);
return;
}
} else {
demux = WebPDemux(&webp_data);
if (!demux) return;
}
WebPChunkIterator chunk_iter;
if (WebPDemuxGetChunk(demux, "EXIF", 1, &chunk_iter)) {
(void)WebPDemuxNextChunk(&chunk_iter);
}
WebPDemuxReleaseChunkIterator(&chunk_iter);
if (WebPDemuxGetChunk(demux, "ICCP", 0, &chunk_iter)) { // 0 == last
(void)WebPDemuxPrevChunk(&chunk_iter);
}
WebPDemuxReleaseChunkIterator(&chunk_iter);
// Skips FUZZ because the Demux API has no concept of (un)known chunks.
WebPIterator iter;
if (WebPDemuxGetFrame(demux, 1, &iter)) {
for (int i = 1; i < fuzz_utils::kFuzzFrameLimit; i++) {
if (!WebPDemuxNextFrame(&iter)) break;
}
}
WebPDemuxReleaseIterator(&iter);
WebPDemuxDelete(demux);
}
}
} // namespace
FUZZ_TEST(MuxDemuxApi, MuxDemuxApiTest)
.WithDomains(
fuzztest::String()
.WithMaxSize(fuzz_utils::kMaxWebPFileSize + 1),
/*mux=*/fuzztest::Arbitrary<bool>());