diff options
Diffstat (limited to 'tests/fuzzer/mux_demux_api_fuzzer.c')
-rw-r--r-- | tests/fuzzer/mux_demux_api_fuzzer.c | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/tests/fuzzer/mux_demux_api_fuzzer.c b/tests/fuzzer/mux_demux_api_fuzzer.c new file mode 100644 index 00000000..a8f81bf1 --- /dev/null +++ b/tests/fuzzer/mux_demux_api_fuzzer.c @@ -0,0 +1,96 @@ +// 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 "./fuzz_utils.h" +#include "webp/demux.h" +#include "webp/mux.h" + +int LLVMFuzzerTestOneInput(const uint8_t* const data, size_t size) { + WebPData webp_data; + WebPDataInit(&webp_data); + webp_data.size = size; + webp_data.bytes = data; + + // Extracted chunks and frames are not processed or decoded, + // which is already covered extensively by the other fuzz targets. + + if (size & 1) { + // Mux API + WebPMux* mux = WebPMuxCreate(&webp_data, size & 2); + if (!mux) return 0; + + WebPData chunk; + WebPMuxGetChunk(mux, "EXIF", &chunk); + WebPMuxGetChunk(mux, "ICCP", &chunk); + WebPMuxGetChunk(mux, "FUZZ", &chunk); // unknown + + uint32_t flags; + WebPMuxGetFeatures(mux, &flags); + + WebPMuxAnimParams params; + WebPMuxGetAnimationParams(mux, ¶ms); + + WebPMuxError status; + WebPMuxFrameInfo info; + for (int i = 0; i < 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 0; + } + } else { + demux = WebPDemux(&webp_data); + if (!demux) return 0; + } + + WebPChunkIterator chunk_iter; + if (WebPDemuxGetChunk(demux, "EXIF", 1, &chunk_iter)) { + WebPDemuxNextChunk(&chunk_iter); + } + WebPDemuxReleaseChunkIterator(&chunk_iter); + if (WebPDemuxGetChunk(demux, "ICCP", 0, &chunk_iter)) { // 0 == last + 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 < kFuzzFrameLimit; i++) { + if (!WebPDemuxNextFrame(&iter)) break; + } + } + + WebPDemuxReleaseIterator(&iter); + WebPDemuxDelete(demux); + } + + return 0; +} |