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/decode.h" |
19 | | |
20 | 3.76k | int LLVMFuzzerTestOneInput(const uint8_t* const data, size_t size) { |
21 | 3.76k | int w, h; |
22 | 3.76k | if (!WebPGetInfo(data, size, &w, &h)) return 0; |
23 | 3.29k | if ((size_t)w * h > kFuzzPxLimit) return 0; |
24 | 3.26k | |
25 | 3.26k | const uint8_t value = FuzzHash(data, size); |
26 | 3.26k | uint8_t* buf = NULL; |
27 | 3.26k | |
28 | 3.26k | // For *Into functions, which decode into an external buffer, an |
29 | 3.26k | // intentionally too small buffer can be given with low probability. |
30 | 3.26k | if (value < 0x16) { |
31 | 306 | buf = WebPDecodeRGBA(data, size, &w, &h); |
32 | 2.95k | } else if (value < 0x2b) { |
33 | 266 | buf = WebPDecodeARGB(data, size, &w, &h); |
34 | 2.69k | } else if (value < 0x40) { |
35 | 273 | buf = WebPDecodeBGRA(data, size, &w, &h); |
36 | 2.41k | } else if (value < 0x55) { |
37 | 307 | buf = WebPDecodeRGB(data, size, &w, &h); |
38 | 2.11k | } else if (value < 0x6a) { |
39 | 278 | buf = WebPDecodeBGR(data, size, &w, &h); |
40 | 1.83k | } else if (value < 0x7f) { |
41 | 239 | uint8_t *u, *v; |
42 | 239 | int stride, uv_stride; |
43 | 239 | buf = WebPDecodeYUV(data, size, &w, &h, &u, &v, &stride, &uv_stride); |
44 | 1.59k | } else if (value < 0xe8) { |
45 | 1.28k | const int stride = (value < 0xbe ? 4 : 3) * w; |
46 | 1.28k | size_t buf_size = stride * h; |
47 | 1.28k | if (value % 0x10 == 0) buf_size--; |
48 | 1.28k | uint8_t* const ext_buf = (uint8_t*)malloc(buf_size); |
49 | 1.28k | if (value < 0x94) { |
50 | 255 | WebPDecodeRGBAInto(data, size, ext_buf, buf_size, stride); |
51 | 1.03k | } else if (value < 0xa9) { |
52 | 250 | WebPDecodeARGBInto(data, size, ext_buf, buf_size, stride); |
53 | 783 | } else if (value < 0xbe) { |
54 | 276 | WebPDecodeBGRAInto(data, size, ext_buf, buf_size, stride); |
55 | 507 | } else if (value < 0xd3) { |
56 | 271 | WebPDecodeRGBInto(data, size, ext_buf, buf_size, stride); |
57 | 271 | } else { |
58 | 236 | WebPDecodeBGRInto(data, size, ext_buf, buf_size, stride); |
59 | 236 | } |
60 | 1.28k | free(ext_buf); |
61 | 1.28k | } else { |
62 | 306 | size_t luma_size = w * h; |
63 | 306 | const int uv_stride = (w + 1) / 2; |
64 | 306 | size_t u_size = uv_stride * (h + 1) / 2; |
65 | 306 | size_t v_size = uv_stride * (h + 1) / 2; |
66 | 306 | if (value % 0x10 == 0) { |
67 | 37 | if (size & 1) luma_size--; |
68 | 37 | if (size & 2) u_size--; |
69 | 37 | if (size & 4) v_size--; |
70 | 37 | } |
71 | 306 | uint8_t* const luma_buf = (uint8_t*)malloc(luma_size); |
72 | 306 | uint8_t* const u_buf = (uint8_t*)malloc(u_size); |
73 | 306 | uint8_t* const v_buf = (uint8_t*)malloc(v_size); |
74 | 306 | WebPDecodeYUVInto(data, size, luma_buf, luma_size, w /* luma_stride */, |
75 | 306 | u_buf, u_size, uv_stride, v_buf, v_size, uv_stride); |
76 | 306 | free(luma_buf); |
77 | 306 | free(u_buf); |
78 | 306 | free(v_buf); |
79 | 306 | } |
80 | 3.26k | |
81 | 3.26k | if (buf) WebPFree(buf); |
82 | 3.26k | |
83 | 3.26k | return 0; |
84 | 3.26k | } |