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