Coverage Report

Created: 2025-11-09 06:12

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.82k
void MuxDemuxApiTest(std::string_view data_in, bool use_mux_api) {
29
2.82k
  const size_t size = data_in.size();
30
2.82k
  WebPData webp_data;
31
2.82k
  WebPDataInit(&webp_data);
32
2.82k
  webp_data.size = size;
33
2.82k
  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.82k
  if (use_mux_api) {
39
    // Mux API
40
1.00k
    WebPMux* mux = WebPMuxCreate(&webp_data, size & 2);
41
1.00k
    if (!mux) return;
42
43
319
    WebPData chunk;
44
319
    (void)WebPMuxGetChunk(mux, "EXIF", &chunk);
45
319
    (void)WebPMuxGetChunk(mux, "ICCP", &chunk);
46
319
    (void)WebPMuxGetChunk(mux, "FUZZ", &chunk);  // unknown
47
48
319
    uint32_t flags;
49
319
    (void)WebPMuxGetFeatures(mux, &flags);
50
51
319
    WebPMuxAnimParams params;
52
319
    (void)WebPMuxGetAnimationParams(mux, &params);
53
54
319
    WebPMuxError status;
55
319
    WebPMuxFrameInfo info;
56
638
    for (int i = 0; i < fuzz_utils::kFuzzFrameLimit; i++) {
57
638
      status = WebPMuxGetFrame(mux, i + 1, &info);
58
638
      if (status == WEBP_MUX_NOT_FOUND) {
59
319
        break;
60
319
      } else if (status == WEBP_MUX_OK) {
61
319
        WebPDataClear(&info.bitstream);
62
319
      }
63
638
    }
64
65
319
    WebPMuxDelete(mux);
66
1.82k
  } else {
67
    // Demux API
68
1.82k
    WebPDemuxer* demux;
69
1.82k
    if (size & 2) {
70
1.31k
      WebPDemuxState state;
71
1.31k
      demux = WebPDemuxPartial(&webp_data, &state);
72
1.31k
      if (state < WEBP_DEMUX_PARSED_HEADER) {
73
628
        WebPDemuxDelete(demux);
74
628
        return;
75
628
      }
76
1.31k
    } else {
77
514
      demux = WebPDemux(&webp_data);
78
514
      if (!demux) return;
79
514
    }
80
81
743
    WebPChunkIterator chunk_iter;
82
743
    if (WebPDemuxGetChunk(demux, "EXIF", 1, &chunk_iter)) {
83
16
      (void)WebPDemuxNextChunk(&chunk_iter);
84
16
    }
85
743
    WebPDemuxReleaseChunkIterator(&chunk_iter);
86
743
    if (WebPDemuxGetChunk(demux, "ICCP", 0, &chunk_iter)) {  // 0 == last
87
2
      (void)WebPDemuxPrevChunk(&chunk_iter);
88
2
    }
89
743
    WebPDemuxReleaseChunkIterator(&chunk_iter);
90
    // Skips FUZZ because the Demux API has no concept of (un)known chunks.
91
92
743
    WebPIterator iter;
93
743
    if (WebPDemuxGetFrame(demux, 1, &iter)) {
94
435
      for (int i = 1; i < fuzz_utils::kFuzzFrameLimit; i++) {
95
435
        if (!WebPDemuxNextFrame(&iter)) break;
96
435
      }
97
435
    }
98
99
743
    WebPDemuxReleaseIterator(&iter);
100
743
    WebPDemuxDelete(demux);
101
743
  }
102
2.82k
}
103
104
}  // namespace
105
106
FUZZ_TEST(MuxDemuxApi, MuxDemuxApiTest)
107
    .WithDomains(fuzztest::String().WithMaxSize(fuzz_utils::kMaxWebPFileSize +
108
                                                1),
109
                 /*mux=*/fuzztest::Arbitrary<bool>());