mux_demux_api_fuzzer.cc (3278B)
1 // Copyright 2018 Google Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 //////////////////////////////////////////////////////////////////////////////// 16 17 #include <cstddef> 18 #include <cstdint> 19 #include <string_view> 20 21 #include "./fuzz_utils.h" 22 #include "src/webp/demux.h" 23 #include "src/webp/mux.h" 24 #include "src/webp/mux_types.h" 25 26 namespace { 27 28 void MuxDemuxApiTest(std::string_view data_in, bool use_mux_api) { 29 const size_t size = data_in.size(); 30 WebPData webp_data; 31 WebPDataInit(&webp_data); 32 webp_data.size = size; 33 webp_data.bytes = reinterpret_cast<const uint8_t*>(data_in.data()); 34 35 // Extracted chunks and frames are not processed or decoded, 36 // which is already covered extensively by the other fuzz targets. 37 38 if (use_mux_api) { 39 // Mux API 40 WebPMux* mux = WebPMuxCreate(&webp_data, size & 2); 41 if (!mux) return; 42 43 WebPData chunk; 44 (void)WebPMuxGetChunk(mux, "EXIF", &chunk); 45 (void)WebPMuxGetChunk(mux, "ICCP", &chunk); 46 (void)WebPMuxGetChunk(mux, "FUZZ", &chunk); // unknown 47 48 uint32_t flags; 49 (void)WebPMuxGetFeatures(mux, &flags); 50 51 WebPMuxAnimParams params; 52 (void)WebPMuxGetAnimationParams(mux, ¶ms); 53 54 WebPMuxError status; 55 WebPMuxFrameInfo info; 56 for (int i = 0; i < fuzz_utils::kFuzzFrameLimit; i++) { 57 status = WebPMuxGetFrame(mux, i + 1, &info); 58 if (status == WEBP_MUX_NOT_FOUND) { 59 break; 60 } else if (status == WEBP_MUX_OK) { 61 WebPDataClear(&info.bitstream); 62 } 63 } 64 65 WebPMuxDelete(mux); 66 } else { 67 // Demux API 68 WebPDemuxer* demux; 69 if (size & 2) { 70 WebPDemuxState state; 71 demux = WebPDemuxPartial(&webp_data, &state); 72 if (state < WEBP_DEMUX_PARSED_HEADER) { 73 WebPDemuxDelete(demux); 74 return; 75 } 76 } else { 77 demux = WebPDemux(&webp_data); 78 if (!demux) return; 79 } 80 81 WebPChunkIterator chunk_iter; 82 if (WebPDemuxGetChunk(demux, "EXIF", 1, &chunk_iter)) { 83 (void)WebPDemuxNextChunk(&chunk_iter); 84 } 85 WebPDemuxReleaseChunkIterator(&chunk_iter); 86 if (WebPDemuxGetChunk(demux, "ICCP", 0, &chunk_iter)) { // 0 == last 87 (void)WebPDemuxPrevChunk(&chunk_iter); 88 } 89 WebPDemuxReleaseChunkIterator(&chunk_iter); 90 // Skips FUZZ because the Demux API has no concept of (un)known chunks. 91 92 WebPIterator iter; 93 if (WebPDemuxGetFrame(demux, 1, &iter)) { 94 for (int i = 1; i < fuzz_utils::kFuzzFrameLimit; i++) { 95 if (!WebPDemuxNextFrame(&iter)) break; 96 } 97 } 98 99 WebPDemuxReleaseIterator(&iter); 100 WebPDemuxDelete(demux); 101 } 102 } 103 104 } // namespace 105 106 FUZZ_TEST(MuxDemuxApi, MuxDemuxApiTest) 107 .WithDomains( 108 fuzztest::String() 109 .WithMaxSize(fuzz_utils::kMaxWebPFileSize + 1), 110 /*mux=*/fuzztest::Arbitrary<bool>());