Coverage Report

Created: 2025-10-10 06:21

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libwebp/tests/fuzzer/mux_demux_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 <string_view>
20
21
#include "./fuzz_utils.h"
22
#include "src/webp/demux.h"
23
#include "src/webp/mux.h"
24
#include "src/webp/mux_types.h"
25
26
namespace {
27
28
2.74k
void MuxDemuxApiTest(std::string_view data_in, bool use_mux_api) {
29
2.74k
  const size_t size = data_in.size();
30
2.74k
  WebPData webp_data;
31
2.74k
  WebPDataInit(&webp_data);
32
2.74k
  webp_data.size = size;
33
2.74k
  webp_data.bytes = reinterpret_cast<const uint8_t*>(data_in.data());
34
35
  // Extracted chunks and frames are not processed or decoded,
36
  // which is already covered extensively by the other fuzz targets.
37
38
2.74k
  if (use_mux_api) {
39
    // Mux API
40
970
    WebPMux* mux = WebPMuxCreate(&webp_data, size & 2);
41
970
    if (!mux) return;
42
43
306
    WebPData chunk;
44
306
    (void)WebPMuxGetChunk(mux, "EXIF", &chunk);
45
306
    (void)WebPMuxGetChunk(mux, "ICCP", &chunk);
46
306
    (void)WebPMuxGetChunk(mux, "FUZZ", &chunk);  // unknown
47
48
306
    uint32_t flags;
49
306
    (void)WebPMuxGetFeatures(mux, &flags);
50
51
306
    WebPMuxAnimParams params;
52
306
    (void)WebPMuxGetAnimationParams(mux, &params);
53
54
306
    WebPMuxError status;
55
306
    WebPMuxFrameInfo info;
56
612
    for (int i = 0; i < fuzz_utils::kFuzzFrameLimit; i++) {
57
612
      status = WebPMuxGetFrame(mux, i + 1, &info);
58
612
      if (status == WEBP_MUX_NOT_FOUND) {
59
306
        break;
60
306
      } else if (status == WEBP_MUX_OK) {
61
306
        WebPDataClear(&info.bitstream);
62
306
      }
63
612
    }
64
65
306
    WebPMuxDelete(mux);
66
1.77k
  } else {
67
    // Demux API
68
1.77k
    WebPDemuxer* demux;
69
1.77k
    if (size & 2) {
70
1.24k
      WebPDemuxState state;
71
1.24k
      demux = WebPDemuxPartial(&webp_data, &state);
72
1.24k
      if (state < WEBP_DEMUX_PARSED_HEADER) {
73
607
        WebPDemuxDelete(demux);
74
607
        return;
75
607
      }
76
1.24k
    } else {
77
530
      demux = WebPDemux(&webp_data);
78
530
      if (!demux) return;
79
530
    }
80
81
696
    WebPChunkIterator chunk_iter;
82
696
    if (WebPDemuxGetChunk(demux, "EXIF", 1, &chunk_iter)) {
83
19
      (void)WebPDemuxNextChunk(&chunk_iter);
84
19
    }
85
696
    WebPDemuxReleaseChunkIterator(&chunk_iter);
86
696
    if (WebPDemuxGetChunk(demux, "ICCP", 0, &chunk_iter)) {  // 0 == last
87
1
      (void)WebPDemuxPrevChunk(&chunk_iter);
88
1
    }
89
696
    WebPDemuxReleaseChunkIterator(&chunk_iter);
90
    // Skips FUZZ because the Demux API has no concept of (un)known chunks.
91
92
696
    WebPIterator iter;
93
696
    if (WebPDemuxGetFrame(demux, 1, &iter)) {
94
436
      for (int i = 1; i < fuzz_utils::kFuzzFrameLimit; i++) {
95
436
        if (!WebPDemuxNextFrame(&iter)) break;
96
436
      }
97
436
    }
98
99
696
    WebPDemuxReleaseIterator(&iter);
100
696
    WebPDemuxDelete(demux);
101
696
  }
102
2.74k
}
103
104
}  // namespace
105
106
FUZZ_TEST(MuxDemuxApi, MuxDemuxApiTest)
107
    .WithDomains(fuzztest::String().WithMaxSize(fuzz_utils::kMaxWebPFileSize +
108
                                                1),
109
                 /*mux=*/fuzztest::Arbitrary<bool>());