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