Coverage Report

Created: 2018-12-03 14:26

/src/fuzz_animation_api.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.h"
18
#include "webp/decode.h"
19
#include "webp/demux.h"
20
#include "webp/mux_types.h"
21
22
4.22k
int LLVMFuzzerTestOneInput(const uint8_t* const data, size_t size) {
23
4.22k
  WebPData webp_data;
24
4.22k
  WebPDataInit(&webp_data);
25
4.22k
  webp_data.size = size;
26
4.22k
  webp_data.bytes = data;
27
4.22k
28
4.22k
  // WebPAnimDecoderNew uses WebPDemux internally to calloc canvas size.
29
4.22k
  WebPDemuxer* const demux = WebPDemux(&webp_data);
30
4.22k
  if (!demux) return 0;
31
2.99k
  const uint32_t cw = WebPDemuxGetI(demux, WEBP_FF_CANVAS_WIDTH);
32
2.99k
  const uint32_t ch = WebPDemuxGetI(demux, WEBP_FF_CANVAS_HEIGHT);
33
2.99k
  if ((size_t)cw * ch > kFuzzPxLimit) {
34
47
    WebPDemuxDelete(demux);
35
47
    return 0;
36
47
  }
37
2.94k
38
2.94k
  // In addition to canvas size, check each frame separately.
39
2.94k
  WebPIterator iter;
40
6.37k
  for (int i = 0; i < kFuzzFrameLimit; i++) {
41
6.18k
    if (!WebPDemuxGetFrame(demux, i + 1, &iter)) break;
42
3.42k
    int w, h;
43
3.42k
    if (WebPGetInfo(iter.fragment.bytes, iter.fragment.size, &w, &h)) {
44
3.42k
      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
3.42k
    }
50
3.42k
  }
51
2.94k
52
2.94k
  WebPDemuxReleaseIterator(&iter);
53
2.94k
  WebPDemuxDelete(demux);
54
2.94k
55
2.94k
  WebPAnimDecoderOptions dec_options;
56
2.94k
  if (!WebPAnimDecoderOptionsInit(&dec_options)) return 0;
57
2.94k
58
2.94k
  dec_options.use_threads = size & 1;
59
2.94k
  // Animations only support 4 (of 12) modes.
60
2.94k
  dec_options.color_mode = (WEBP_CSP_MODE)(size % MODE_LAST);
61
2.94k
  if (dec_options.color_mode != MODE_BGRA &&
62
2.94k
      dec_options.color_mode != MODE_rgbA &&
63
2.94k
      dec_options.color_mode != MODE_bgrA) {
64
1.46k
    dec_options.color_mode = MODE_RGBA;
65
1.46k
  }
66
2.94k
67
2.94k
  WebPAnimDecoder* dec = WebPAnimDecoderNew(&webp_data, &dec_options);
68
2.94k
  if (!dec) return 0;
69
2.94k
70
4.23k
  for (int i = 0; i < kFuzzFrameLimit; i++) {
71
4.08k
    uint8_t* buf;
72
4.08k
    int timestamp;
73
4.08k
    if (!WebPAnimDecoderGetNext(dec, &buf, &timestamp)) break;
74
4.08k
  }
75
2.94k
76
2.94k
  WebPAnimDecoderDelete(dec);
77
2.94k
  return 0;
78
2.94k
}