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 "fuzz.h" |
18 | | #include "webp/mux.h" |
19 | | #include "webp/demux.h" |
20 | | |
21 | 3.00k | int LLVMFuzzerTestOneInput(const uint8_t* const data, size_t size) { |
22 | 3.00k | WebPData webp_data; |
23 | 3.00k | WebPDataInit(&webp_data); |
24 | 3.00k | webp_data.size = size; |
25 | 3.00k | webp_data.bytes = data; |
26 | 3.00k | |
27 | 3.00k | // Extracted chunks and frames are not processed or decoded, |
28 | 3.00k | // which is already covered extensively by the other fuzz targets. |
29 | 3.00k | |
30 | 3.00k | if (size & 1) { |
31 | 999 | // Mux API |
32 | 999 | WebPMux* mux = WebPMuxCreate(&webp_data, size & 2); |
33 | 999 | if (!mux) return 0; |
34 | 204 | |
35 | 204 | WebPData chunk; |
36 | 204 | WebPMuxGetChunk(mux, "EXIF", &chunk); |
37 | 204 | WebPMuxGetChunk(mux, "ICCP", &chunk); |
38 | 204 | WebPMuxGetChunk(mux, "FUZZ", &chunk); // unknown |
39 | 204 | |
40 | 204 | uint32_t flags; |
41 | 204 | WebPMuxGetFeatures(mux, &flags); |
42 | 204 | |
43 | 204 | WebPMuxAnimParams params; |
44 | 204 | WebPMuxGetAnimationParams(mux, ¶ms); |
45 | 204 | |
46 | 204 | WebPMuxError status; |
47 | 204 | WebPMuxFrameInfo info; |
48 | 474 | for (int i = 0; i < kFuzzFrameLimit; i++) { |
49 | 449 | status = WebPMuxGetFrame(mux, i + 1, &info); |
50 | 449 | if (status == WEBP_MUX_NOT_FOUND) { |
51 | 179 | break; |
52 | 270 | } else if (status == WEBP_MUX_OK) { |
53 | 270 | WebPDataClear(&info.bitstream); |
54 | 270 | } |
55 | 449 | } |
56 | 204 | |
57 | 204 | WebPMuxDelete(mux); |
58 | 2.00k | } else { |
59 | 2.00k | // Demux API |
60 | 2.00k | WebPDemuxer* demux; |
61 | 2.00k | if (size & 2) { |
62 | 1.48k | WebPDemuxState state; |
63 | 1.48k | demux = WebPDemuxPartial(&webp_data, &state); |
64 | 1.48k | if (state < WEBP_DEMUX_PARSED_HEADER) { |
65 | 658 | WebPDemuxDelete(demux); |
66 | 658 | return 0; |
67 | 658 | } |
68 | 521 | } else { |
69 | 521 | demux = WebPDemux(&webp_data); |
70 | 521 | if (!demux) return 0; |
71 | 873 | } |
72 | 873 | |
73 | 873 | WebPChunkIterator chunk_iter; |
74 | 873 | if (WebPDemuxGetChunk(demux, "EXIF", 1, &chunk_iter)) { |
75 | 31 | WebPDemuxNextChunk(&chunk_iter); |
76 | 31 | } |
77 | 873 | WebPDemuxReleaseChunkIterator(&chunk_iter); |
78 | 873 | if (WebPDemuxGetChunk(demux, "ICCP", 0, &chunk_iter)) { // 0 == last |
79 | 92 | WebPDemuxPrevChunk(&chunk_iter); |
80 | 92 | } |
81 | 873 | WebPDemuxReleaseChunkIterator(&chunk_iter); |
82 | 873 | // Skips FUZZ because the Demux API has no concept of (un)known chunks. |
83 | 873 | |
84 | 873 | WebPIterator iter; |
85 | 873 | if (WebPDemuxGetFrame(demux, 1, &iter)) { |
86 | 464 | for (int i = 1; i < kFuzzFrameLimit; i++) { |
87 | 421 | if (!WebPDemuxNextFrame(&iter)) break; |
88 | 421 | } |
89 | 373 | } |
90 | 873 | |
91 | 873 | WebPDemuxReleaseIterator(&iter); |
92 | 873 | WebPDemuxDelete(demux); |
93 | 873 | } |
94 | 3.00k | |
95 | 3.00k | return 0; |
96 | 3.00k | } |