Coverage Report

Created: 2023-09-01 06:48

/src/libwebp/tests/fuzzer/animation_api_fuzzer.c
Line
Count
Source (jump to first uncovered line)
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 "./fuzz_utils.h"
18
#include "src/webp/decode.h"
19
#include "src/webp/demux.h"
20
#include "src/webp/mux_types.h"
21
22
5.86k
int LLVMFuzzerTestOneInput(const uint8_t* const data, size_t size) {
23
5.86k
  WebPData webp_data;
24
5.86k
  WebPDataInit(&webp_data);
25
5.86k
  webp_data.size = size;
26
5.86k
  webp_data.bytes = data;
27
28
  // WebPAnimDecoderNew uses WebPDemux internally to calloc canvas size.
29
5.86k
  WebPDemuxer* const demux = WebPDemux(&webp_data);
30
5.86k
  if (!demux) return 0;
31
4.59k
  const uint32_t cw = WebPDemuxGetI(demux, WEBP_FF_CANVAS_WIDTH);
32
4.59k
  const uint32_t ch = WebPDemuxGetI(demux, WEBP_FF_CANVAS_HEIGHT);
33
4.59k
  if ((size_t)cw * ch > kFuzzPxLimit) {
34
145
    WebPDemuxDelete(demux);
35
145
    return 0;
36
145
  }
37
38
  // In addition to canvas size, check each frame separately.
39
4.45k
  WebPIterator iter;
40
9.34k
  for (int i = 0; i < kFuzzFrameLimit; i++) {
41
9.18k
    if (!WebPDemuxGetFrame(demux, i + 1, &iter)) break;
42
4.89k
    int w, h;
43
4.89k
    if (WebPGetInfo(iter.fragment.bytes, iter.fragment.size, &w, &h)) {
44
4.89k
      if ((size_t)w * h > kFuzzPxLimit) {  // image size of the frame payload
45
0
        WebPDemuxReleaseIterator(&iter);
46
0
        WebPDemuxDelete(demux);
47
0
        return 0;
48
0
      }
49
4.89k
    }
50
4.89k
  }
51
52
4.45k
  WebPDemuxReleaseIterator(&iter);
53
4.45k
  WebPDemuxDelete(demux);
54
55
4.45k
  WebPAnimDecoderOptions dec_options;
56
4.45k
  if (!WebPAnimDecoderOptionsInit(&dec_options)) return 0;
57
58
4.45k
  dec_options.use_threads = size & 1;
59
  // Animations only support 4 (of 12) modes.
60
4.45k
  dec_options.color_mode = (WEBP_CSP_MODE)(size % MODE_LAST);
61
4.45k
  if (dec_options.color_mode != MODE_BGRA &&
62
4.45k
      dec_options.color_mode != MODE_rgbA &&
63
4.45k
      dec_options.color_mode != MODE_bgrA) {
64
2.35k
    dec_options.color_mode = MODE_RGBA;
65
2.35k
  }
66
67
4.45k
  WebPAnimDecoder* dec = WebPAnimDecoderNew(&webp_data, &dec_options);
68
4.45k
  if (!dec) return 0;
69
70
5.94k
  for (int i = 0; i < kFuzzFrameLimit; i++) {
71
5.81k
    uint8_t* buf;
72
5.81k
    int timestamp;
73
5.81k
    if (!WebPAnimDecoderGetNext(dec, &buf, &timestamp)) break;
74
5.81k
  }
75
76
4.44k
  WebPAnimDecoderDelete(dec);
77
4.44k
  return 0;
78
4.45k
}