xref: /aosp_15_r20/external/webp/tests/fuzzer/animation_api_fuzzer.c (revision b2055c353e87c8814eb2b6b1b11112a1562253bd)
1*b2055c35SXin Li // Copyright 2018 Google Inc.
2*b2055c35SXin Li //
3*b2055c35SXin Li // Licensed under the Apache License, Version 2.0 (the "License");
4*b2055c35SXin Li // you may not use this file except in compliance with the License.
5*b2055c35SXin Li // You may obtain a copy of the License at
6*b2055c35SXin Li //
7*b2055c35SXin Li //      http://www.apache.org/licenses/LICENSE-2.0
8*b2055c35SXin Li //
9*b2055c35SXin Li // Unless required by applicable law or agreed to in writing, software
10*b2055c35SXin Li // distributed under the License is distributed on an "AS IS" BASIS,
11*b2055c35SXin Li // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*b2055c35SXin Li // See the License for the specific language governing permissions and
13*b2055c35SXin Li // limitations under the License.
14*b2055c35SXin Li //
15*b2055c35SXin Li ////////////////////////////////////////////////////////////////////////////////
16*b2055c35SXin Li 
17*b2055c35SXin Li #include "./fuzz_utils.h"
18*b2055c35SXin Li #include "src/webp/decode.h"
19*b2055c35SXin Li #include "src/webp/demux.h"
20*b2055c35SXin Li #include "src/webp/mux_types.h"
21*b2055c35SXin Li 
LLVMFuzzerTestOneInput(const uint8_t * const data,size_t size)22*b2055c35SXin Li int LLVMFuzzerTestOneInput(const uint8_t* const data, size_t size) {
23*b2055c35SXin Li   WebPData webp_data;
24*b2055c35SXin Li   WebPDataInit(&webp_data);
25*b2055c35SXin Li   webp_data.size = size;
26*b2055c35SXin Li   webp_data.bytes = data;
27*b2055c35SXin Li 
28*b2055c35SXin Li   // WebPAnimDecoderNew uses WebPDemux internally to calloc canvas size.
29*b2055c35SXin Li   WebPDemuxer* const demux = WebPDemux(&webp_data);
30*b2055c35SXin Li   if (!demux) return 0;
31*b2055c35SXin Li   const uint32_t cw = WebPDemuxGetI(demux, WEBP_FF_CANVAS_WIDTH);
32*b2055c35SXin Li   const uint32_t ch = WebPDemuxGetI(demux, WEBP_FF_CANVAS_HEIGHT);
33*b2055c35SXin Li   if ((size_t)cw * ch > kFuzzPxLimit) {
34*b2055c35SXin Li     WebPDemuxDelete(demux);
35*b2055c35SXin Li     return 0;
36*b2055c35SXin Li   }
37*b2055c35SXin Li 
38*b2055c35SXin Li   // In addition to canvas size, check each frame separately.
39*b2055c35SXin Li   WebPIterator iter;
40*b2055c35SXin Li   for (int i = 0; i < kFuzzFrameLimit; i++) {
41*b2055c35SXin Li     if (!WebPDemuxGetFrame(demux, i + 1, &iter)) break;
42*b2055c35SXin Li     int w, h;
43*b2055c35SXin Li     if (WebPGetInfo(iter.fragment.bytes, iter.fragment.size, &w, &h)) {
44*b2055c35SXin Li       if ((size_t)w * h > kFuzzPxLimit) {  // image size of the frame payload
45*b2055c35SXin Li         WebPDemuxReleaseIterator(&iter);
46*b2055c35SXin Li         WebPDemuxDelete(demux);
47*b2055c35SXin Li         return 0;
48*b2055c35SXin Li       }
49*b2055c35SXin Li     }
50*b2055c35SXin Li   }
51*b2055c35SXin Li 
52*b2055c35SXin Li   WebPDemuxReleaseIterator(&iter);
53*b2055c35SXin Li   WebPDemuxDelete(demux);
54*b2055c35SXin Li 
55*b2055c35SXin Li   WebPAnimDecoderOptions dec_options;
56*b2055c35SXin Li   if (!WebPAnimDecoderOptionsInit(&dec_options)) return 0;
57*b2055c35SXin Li 
58*b2055c35SXin Li   dec_options.use_threads = size & 1;
59*b2055c35SXin Li   // Animations only support 4 (of 12) modes.
60*b2055c35SXin Li   dec_options.color_mode = (WEBP_CSP_MODE)(size % MODE_LAST);
61*b2055c35SXin Li   if (dec_options.color_mode != MODE_BGRA &&
62*b2055c35SXin Li       dec_options.color_mode != MODE_rgbA &&
63*b2055c35SXin Li       dec_options.color_mode != MODE_bgrA) {
64*b2055c35SXin Li     dec_options.color_mode = MODE_RGBA;
65*b2055c35SXin Li   }
66*b2055c35SXin Li 
67*b2055c35SXin Li   WebPAnimDecoder* dec = WebPAnimDecoderNew(&webp_data, &dec_options);
68*b2055c35SXin Li   if (!dec) return 0;
69*b2055c35SXin Li 
70*b2055c35SXin Li   for (int i = 0; i < kFuzzFrameLimit; i++) {
71*b2055c35SXin Li     uint8_t* buf;
72*b2055c35SXin Li     int timestamp;
73*b2055c35SXin Li     if (!WebPAnimDecoderGetNext(dec, &buf, &timestamp)) break;
74*b2055c35SXin Li   }
75*b2055c35SXin Li 
76*b2055c35SXin Li   WebPAnimDecoderDelete(dec);
77*b2055c35SXin Li   return 0;
78*b2055c35SXin Li }
79