/src/libwebp/tests/fuzzer/simple_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 <cstdlib> |
20 | | #include <string> |
21 | | #include <string_view> |
22 | | |
23 | | #include "./fuzz_utils.h" |
24 | | #include "gtest/gtest.h" |
25 | | #include "webp/decode.h" |
26 | | #include "webp/types.h" |
27 | | |
28 | | namespace { |
29 | | |
30 | 5.61k | void SimpleApiTest(std::string_view data_in) { |
31 | 5.61k | const uint8_t* const data = reinterpret_cast<const uint8_t*>(data_in.data()); |
32 | 5.61k | const size_t size = data_in.size(); |
33 | 5.61k | int w, h; |
34 | 5.61k | if (!WebPGetInfo(data, size, &w, &h)) return; |
35 | 5.28k | if ((size_t)w * h > fuzz_utils::kFuzzPxLimit) return; |
36 | | |
37 | 5.26k | const uint8_t value = fuzz_utils::FuzzHash(data, size); |
38 | 5.26k | uint8_t* buf = NULL; |
39 | | |
40 | | // For *Into functions, which decode into an external buffer, an |
41 | | // intentionally too small buffer can be given with low probability. |
42 | 5.26k | if (value < 0x16) { |
43 | 480 | buf = WebPDecodeRGBA(data, size, &w, &h); |
44 | 4.78k | } else if (value < 0x2b) { |
45 | 565 | buf = WebPDecodeBGRA(data, size, &w, &h); |
46 | 565 | #if !defined(WEBP_REDUCE_CSP) |
47 | 4.21k | } else if (value < 0x40) { |
48 | 490 | buf = WebPDecodeARGB(data, size, &w, &h); |
49 | 3.72k | } else if (value < 0x55) { |
50 | 448 | buf = WebPDecodeRGB(data, size, &w, &h); |
51 | 3.27k | } else if (value < 0x6a) { |
52 | 425 | buf = WebPDecodeBGR(data, size, &w, &h); |
53 | 425 | #endif // !defined(WEBP_REDUCE_CSP) |
54 | 2.85k | } else if (value < 0x7f) { |
55 | 423 | uint8_t *u, *v; |
56 | 423 | int stride, uv_stride; |
57 | 423 | buf = WebPDecodeYUV(data, size, &w, &h, &u, &v, &stride, &uv_stride); |
58 | 2.43k | } else if (value < 0xe8) { |
59 | 1.95k | const int stride = (value < 0xbe ? 4 : 3) * w; |
60 | 1.95k | size_t buf_size = stride * h; |
61 | 1.95k | if (value % 0x10 == 0) buf_size--; |
62 | 1.95k | uint8_t* const ext_buf = (uint8_t*)malloc(buf_size); |
63 | 1.95k | if (value < 0x94) { |
64 | 455 | (void)WebPDecodeRGBAInto(data, size, ext_buf, buf_size, stride); |
65 | 455 | #if !defined(WEBP_REDUCE_CSP) |
66 | 1.49k | } else if (value < 0xa9) { |
67 | 447 | (void)WebPDecodeARGBInto(data, size, ext_buf, buf_size, stride); |
68 | 1.05k | } else if (value < 0xbe) { |
69 | 498 | (void)WebPDecodeBGRInto(data, size, ext_buf, buf_size, stride); |
70 | 554 | } else if (value < 0xd3) { |
71 | 436 | (void)WebPDecodeRGBInto(data, size, ext_buf, buf_size, stride); |
72 | 436 | #endif // !defined(WEBP_REDUCE_CSP) |
73 | 436 | } else { |
74 | 118 | (void)WebPDecodeBGRAInto(data, size, ext_buf, buf_size, stride); |
75 | 118 | } |
76 | 1.95k | free(ext_buf); |
77 | 1.95k | } else { |
78 | 476 | size_t luma_size = w * h; |
79 | 476 | const int uv_stride = (w + 1) / 2; |
80 | 476 | size_t u_size = uv_stride * (h + 1) / 2; |
81 | 476 | size_t v_size = uv_stride * (h + 1) / 2; |
82 | 476 | if (value % 0x10 == 0) { |
83 | 25 | if (size & 1) luma_size--; |
84 | 25 | if (size & 2) u_size--; |
85 | 25 | if (size & 4) v_size--; |
86 | 25 | } |
87 | 476 | uint8_t* const luma_buf = (uint8_t*)malloc(luma_size); |
88 | 476 | uint8_t* const u_buf = (uint8_t*)malloc(u_size); |
89 | 476 | uint8_t* const v_buf = (uint8_t*)malloc(v_size); |
90 | 476 | (void)WebPDecodeYUVInto(data, size, luma_buf, luma_size, |
91 | 476 | w /* luma_stride */, u_buf, u_size, uv_stride, |
92 | 476 | v_buf, v_size, uv_stride); |
93 | 476 | free(luma_buf); |
94 | 476 | free(u_buf); |
95 | 476 | free(v_buf); |
96 | 476 | } |
97 | | |
98 | 5.26k | if (buf) WebPFree(buf); |
99 | 5.26k | } |
100 | | |
101 | | } // namespace |
102 | | |
103 | | FUZZ_TEST(SimpleApi, SimpleApiTest) |
104 | | .WithDomains(fuzztest::String().WithMaxSize(fuzz_utils::kMaxWebPFileSize + |
105 | | 1)); |
106 | | |
107 | 0 | TEST(SimpleApi, Buganizer498966511) { |
108 | 0 | SimpleApiTest( |
109 | 0 | std::string("ALPH\004\000\000\000A\377\377\377\377LP\010\000\000\000\000" |
110 | 0 | "\000\000\311H\006\000\000\000\"E\356PW\"ALPH\000\000\000\000" |
111 | 0 | "ALpH\004\000\000\000\004\010\000\200VP8 " |
112 | 0 | "T\000\000\000\266\003\000\235\001*" |
113 | 0 | "\001\000\002\000y\336n\366\001O\363\374\243\000\003LPS\"\002" |
114 | 0 | "iF\000FjRsa\232vP\"EO\"K\217OM;rOect\275n\"Wsection_JUNQ=" |
115 | 0 | "\"JUNQ\"\250YO,_I\362\021\"ANIM\"", |
116 | 0 | 150)); |
117 | 0 | } |