animation_api_fuzzer.cc (2959B)
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/decode.h" 23 #include "src/webp/demux.h" 24 #include "src/webp/mux_types.h" 25 26 namespace { 27 28 void AnimationApiTest(std::string_view blob, bool use_threads, 29 WEBP_CSP_MODE color_mode) { 30 const size_t size = blob.size(); 31 WebPData webp_data; 32 WebPDataInit(&webp_data); 33 webp_data.size = size; 34 webp_data.bytes = reinterpret_cast<const uint8_t*>(blob.data()); 35 36 // WebPAnimDecoderNew uses WebPDemux internally to calloc canvas size. 37 WebPDemuxer* const demux = WebPDemux(&webp_data); 38 if (!demux) return; 39 const uint32_t cw = WebPDemuxGetI(demux, WEBP_FF_CANVAS_WIDTH); 40 const uint32_t ch = WebPDemuxGetI(demux, WEBP_FF_CANVAS_HEIGHT); 41 if ((size_t)cw * ch > fuzz_utils::kFuzzPxLimit) { 42 WebPDemuxDelete(demux); 43 return; 44 } 45 46 // In addition to canvas size, check each frame separately. 47 WebPIterator iter; 48 for (int i = 0; i < fuzz_utils::kFuzzFrameLimit; i++) { 49 if (!WebPDemuxGetFrame(demux, i + 1, &iter)) break; 50 int w, h; 51 if (WebPGetInfo(iter.fragment.bytes, iter.fragment.size, &w, &h)) { 52 if ((size_t)w * h > 53 fuzz_utils::kFuzzPxLimit) { // image size of the frame payload 54 WebPDemuxReleaseIterator(&iter); 55 WebPDemuxDelete(demux); 56 return; 57 } 58 } 59 } 60 61 WebPDemuxReleaseIterator(&iter); 62 WebPDemuxDelete(demux); 63 64 WebPAnimDecoderOptions dec_options; 65 if (!WebPAnimDecoderOptionsInit(&dec_options)) return; 66 67 dec_options.use_threads = use_threads; 68 dec_options.color_mode = color_mode; 69 70 WebPAnimDecoder* dec = WebPAnimDecoderNew(&webp_data, &dec_options); 71 if (!dec) return; 72 73 for (int i = 0; i < fuzz_utils::kFuzzFrameLimit; i++) { 74 uint8_t* buf; 75 int timestamp; 76 if (!WebPAnimDecoderGetNext(dec, &buf, ×tamp)) break; 77 } 78 79 WebPAnimDecoderDelete(dec); 80 } 81 82 } // namespace 83 84 FUZZ_TEST(AnimationApi, AnimationApiTest) 85 .WithDomains( 86 fuzztest::String() 87 .WithMaxSize(fuzz_utils::kMaxWebPFileSize + 1), 88 /*use_threads=*/fuzztest::Arbitrary<bool>(), 89 // Animations only support 4 (out of 12) modes. 90 fuzztest::ElementOf<WEBP_CSP_MODE>({MODE_RGBA, MODE_BGRA, MODE_rgbA, 91 MODE_bgrA}));