Coverage Report

Created: 2026-06-10 06:43

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libwebp/tests/fuzzer/simple_api_fuzzer.cc
Line
Count
Source
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 <cstdlib>
20
#include <string>
21
#include <string_view>
22
23
#include "./fuzz_utils.h"
24
#include "gtest/gtest.h"
25
#include "webp/decode.h"
26
#include "webp/types.h"
27
28
namespace {
29
30
5.61k
void SimpleApiTest(std::string_view data_in) {
31
5.61k
  const uint8_t* const data = reinterpret_cast<const uint8_t*>(data_in.data());
32
5.61k
  const size_t size = data_in.size();
33
5.61k
  int w, h;
34
5.61k
  if (!WebPGetInfo(data, size, &w, &h)) return;
35
5.28k
  if ((size_t)w * h > fuzz_utils::kFuzzPxLimit) return;
36
37
5.26k
  const uint8_t value = fuzz_utils::FuzzHash(data, size);
38
5.26k
  uint8_t* buf = NULL;
39
40
  // For *Into functions, which decode into an external buffer, an
41
  // intentionally too small buffer can be given with low probability.
42
5.26k
  if (value < 0x16) {
43
480
    buf = WebPDecodeRGBA(data, size, &w, &h);
44
4.78k
  } else if (value < 0x2b) {
45
565
    buf = WebPDecodeBGRA(data, size, &w, &h);
46
565
#if !defined(WEBP_REDUCE_CSP)
47
4.21k
  } else if (value < 0x40) {
48
490
    buf = WebPDecodeARGB(data, size, &w, &h);
49
3.72k
  } else if (value < 0x55) {
50
448
    buf = WebPDecodeRGB(data, size, &w, &h);
51
3.27k
  } else if (value < 0x6a) {
52
425
    buf = WebPDecodeBGR(data, size, &w, &h);
53
425
#endif  // !defined(WEBP_REDUCE_CSP)
54
2.85k
  } else if (value < 0x7f) {
55
423
    uint8_t *u, *v;
56
423
    int stride, uv_stride;
57
423
    buf = WebPDecodeYUV(data, size, &w, &h, &u, &v, &stride, &uv_stride);
58
2.43k
  } else if (value < 0xe8) {
59
1.95k
    const int stride = (value < 0xbe ? 4 : 3) * w;
60
1.95k
    size_t buf_size = stride * h;
61
1.95k
    if (value % 0x10 == 0) buf_size--;
62
1.95k
    uint8_t* const ext_buf = (uint8_t*)malloc(buf_size);
63
1.95k
    if (value < 0x94) {
64
455
      (void)WebPDecodeRGBAInto(data, size, ext_buf, buf_size, stride);
65
455
#if !defined(WEBP_REDUCE_CSP)
66
1.49k
    } else if (value < 0xa9) {
67
447
      (void)WebPDecodeARGBInto(data, size, ext_buf, buf_size, stride);
68
1.05k
    } else if (value < 0xbe) {
69
498
      (void)WebPDecodeBGRInto(data, size, ext_buf, buf_size, stride);
70
554
    } else if (value < 0xd3) {
71
436
      (void)WebPDecodeRGBInto(data, size, ext_buf, buf_size, stride);
72
436
#endif  // !defined(WEBP_REDUCE_CSP)
73
436
    } else {
74
118
      (void)WebPDecodeBGRAInto(data, size, ext_buf, buf_size, stride);
75
118
    }
76
1.95k
    free(ext_buf);
77
1.95k
  } else {
78
476
    size_t luma_size = w * h;
79
476
    const int uv_stride = (w + 1) / 2;
80
476
    size_t u_size = uv_stride * (h + 1) / 2;
81
476
    size_t v_size = uv_stride * (h + 1) / 2;
82
476
    if (value % 0x10 == 0) {
83
25
      if (size & 1) luma_size--;
84
25
      if (size & 2) u_size--;
85
25
      if (size & 4) v_size--;
86
25
    }
87
476
    uint8_t* const luma_buf = (uint8_t*)malloc(luma_size);
88
476
    uint8_t* const u_buf = (uint8_t*)malloc(u_size);
89
476
    uint8_t* const v_buf = (uint8_t*)malloc(v_size);
90
476
    (void)WebPDecodeYUVInto(data, size, luma_buf, luma_size,
91
476
                            w /* luma_stride */, u_buf, u_size, uv_stride,
92
476
                            v_buf, v_size, uv_stride);
93
476
    free(luma_buf);
94
476
    free(u_buf);
95
476
    free(v_buf);
96
476
  }
97
98
5.26k
  if (buf) WebPFree(buf);
99
5.26k
}
100
101
}  // namespace
102
103
FUZZ_TEST(SimpleApi, SimpleApiTest)
104
    .WithDomains(fuzztest::String().WithMaxSize(fuzz_utils::kMaxWebPFileSize +
105
                                                1));
106
107
0
TEST(SimpleApi, Buganizer498966511) {
108
0
  SimpleApiTest(
109
0
      std::string("ALPH\004\000\000\000A\377\377\377\377LP\010\000\000\000\000"
110
0
                  "\000\000\311H\006\000\000\000\"E\356PW\"ALPH\000\000\000\000"
111
0
                  "ALpH\004\000\000\000\004\010\000\200VP8 "
112
0
                  "T\000\000\000\266\003\000\235\001*"
113
0
                  "\001\000\002\000y\336n\366\001O\363\374\243\000\003LPS\"\002"
114
0
                  "iF\000FjRsa\232vP\"EO\"K\217OM;rOect\275n\"Wsection_JUNQ="
115
0
                  "\"JUNQ\"\250YO,_I\362\021\"ANIM\"",
116
0
                  150));
117
0
}