1 /*
2 * Copyright (c) 2022 Huawei Device Co., Ltd.
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 #include "rsrenderimage_fuzzer.h"
17
18 #include <cstddef>
19 #include <cstdint>
20 #include <securec.h>
21
22 #include "render/rs_blur_filter.h"
23 #include "render/rs_border.h"
24 #include "render/rs_image.h"
25 #include "render/rs_image_cache.h"
26 #include "render/rs_mask.h"
27 #include "render/rs_path.h"
28 #include "render/rs_shader.h"
29 #include "render/rs_shadow.h"
30
31 namespace OHOS {
32 namespace Rosen {
33 namespace {
34 const uint8_t* g_data = nullptr;
35 size_t g_size = 0;
36 size_t g_pos;
37 } // namespace
38
39 /*
40 * describe: get data from outside untrusted data(g_data) which size is according to sizeof(T)
41 * tips: only support basic type
42 */
43 template<class T>
GetData()44 T GetData()
45 {
46 T object {};
47 size_t objectSize = sizeof(object);
48 if (g_data == nullptr || objectSize > g_size - g_pos) {
49 return object;
50 }
51 errno_t ret = memcpy_s(&object, objectSize, g_data + g_pos, objectSize);
52 if (ret != EOK) {
53 return {};
54 }
55 g_pos += objectSize;
56 return object;
57 }
58
59 /*
60 * get a string from g_data
61 */
GetStringFromData(int strlen)62 std::string GetStringFromData(int strlen)
63 {
64 if (strlen <= 0) {
65 return "fuzz";
66 }
67 char cstr[strlen];
68 cstr[strlen - 1] = '\0';
69 for (int i = 0; i < strlen - 1; i++) {
70 char tmp = GetData<char>();
71 if (tmp == '\0') {
72 tmp = '1';
73 }
74 cstr[i] = tmp;
75 }
76 std::string str(cstr);
77 return str;
78 }
79
RSBlurFilterFuzzTest(const uint8_t * data,size_t size)80 bool RSBlurFilterFuzzTest(const uint8_t* data, size_t size)
81 {
82 if (data == nullptr) {
83 return false;
84 }
85
86 // initialize
87 g_data = data;
88 g_size = size;
89 g_pos = 0;
90
91 float blurRadiusX1 = GetData<float>();
92 float blurRadiusY1 = GetData<float>();
93 RSBlurFilter blurFilter(blurRadiusX1, blurRadiusY1);
94 float blurRadiusX2 = GetData<float>();
95 float blurRadiusY2 = GetData<float>();
96 std::shared_ptr<RSFilter> rhs = RSFilter::CreateBlurFilter(blurRadiusX2, blurRadiusY2);
97 float fRhs = GetData<float>();
98
99 blurFilter.Add(rhs);
100 blurFilter.Sub(rhs);
101 blurFilter.Multiply(fRhs);
102
103 return true;
104 }
105
RSBorderFuzzTest(const uint8_t * data,size_t size)106 bool RSBorderFuzzTest(const uint8_t* data, size_t size)
107 {
108 if (data == nullptr) {
109 return false;
110 }
111
112 // initialize
113 g_data = data;
114 g_size = size;
115 g_pos = 0;
116
117 int16_t red1 = GetData<int16_t>();
118 int16_t green1 = GetData<int16_t>();
119 int16_t blue1 = GetData<int16_t>();
120 Color color1(red1, green1, blue1);
121 float width = GetData<float>();
122 BorderStyle style = GetData<BorderStyle>();
123 int idx = GetData<int>();
124 int16_t red2 = GetData<int16_t>();
125 int16_t green2 = GetData<int16_t>();
126 int16_t blue2 = GetData<int16_t>();
127 Color color2(red2, green2, blue2);
128 int16_t red3 = GetData<int16_t>();
129 int16_t green3 = GetData<int16_t>();
130 int16_t blue3 = GetData<int16_t>();
131 Color color3(red3, green3, blue3);
132 int16_t red4 = GetData<int16_t>();
133 int16_t green4 = GetData<int16_t>();
134 int16_t blue4 = GetData<int16_t>();
135 Color color4(red4, green4, blue4);
136 Vector4<Color> vectorColor(color1, color2, color3, color4);
137 float x = GetData<float>();
138 float y = GetData<float>();
139 float z = GetData<float>();
140 float w = GetData<float>();
141 Vector4f vectorWidth(x, y, z, w);
142 uint32_t dataX = GetData<uint32_t>();
143 uint32_t dataY = GetData<uint32_t>();
144 uint32_t dataZ = GetData<uint32_t>();
145 uint32_t dataW = GetData<uint32_t>();
146 Vector4<uint32_t> vectorStyle(dataX, dataY, dataZ, dataW);
147
148 RSBorder border;
149 border.SetColor(color1);
150 border.SetWidth(width);
151 border.SetStyle(style);
152 border.GetColor(idx);
153 border.GetWidth(idx);
154 border.GetStyle(idx);
155 border.SetColorFour(vectorColor);
156 border.SetWidthFour(width);
157 border.SetStyleFour(vectorStyle);
158
159 return true;
160 }
161
RSImageCacheFuzzTest(const uint8_t * data,size_t size)162 bool RSImageCacheFuzzTest(const uint8_t* data, size_t size)
163 {
164 if (data == nullptr) {
165 return false;
166 }
167
168 // initialize
169 g_data = data;
170 g_size = size;
171 g_pos = 0;
172
173 uint64_t uniqueId = GetData<uint64_t>();
174 std::shared_ptr<Drawing::Image> img;
175 RSImageCache::Instance().CacheDrawingImage(uniqueId, img);
176 RSImageCache::Instance().GetDrawingImageCache(uniqueId);
177 RSImageCache::Instance().ReleaseDrawingImageCache(uniqueId);
178
179 return true;
180 }
181
RSImageFuzzTest(const uint8_t * data,size_t size)182 bool RSImageFuzzTest(const uint8_t* data, size_t size)
183 {
184 if (data == nullptr) {
185 return false;
186 }
187
188 // initialize
189 g_data = data;
190 g_size = size;
191 g_pos = 0;
192
193 RSImage other;
194 Drawing::Canvas drawingCanvas;
195 RSPaintFilterCanvas canvas(&drawingCanvas);
196 float fLeft = GetData<float>();
197 float fTop = GetData<float>();
198 float fRight = GetData<float>();
199 float fBottom = GetData<float>();
200 Drawing::Rect rect { fLeft, fTop, fRight, fBottom };
201 Drawing::Brush brush;
202 bool isBackground = GetData<bool>();
203 std::shared_ptr<Drawing::Image> image;
204 float left = GetData<float>();
205 float top = GetData<float>();
206 float right = GetData<float>();
207 float bottom = GetData<float>();
208 RectF dstRect(left, top, right, bottom);
209 int fitNum = GetData<int>();
210 int repeatNum = GetData<int>();
211 float fX1 = GetData<float>();
212 float fY1 = GetData<float>();
213 float fX2 = GetData<float>();
214 float fY2 = GetData<float>();
215 float fX3 = GetData<float>();
216 float fY3 = GetData<float>();
217 float fX4 = GetData<float>();
218 float fY4 = GetData<float>();
219 Drawing::Point vector1 { fX1, fY1 };
220 Drawing::Point vector2 { fX2, fY2 };
221 Drawing::Point vector3 { fX3, fY3 };
222 Drawing::Point vector4 { fX4, fY4 };
223 std::vector<Drawing::Point> radius = { vector1, vector2, vector3, vector4 };
224 double scale = GetData<double>();
225 std::shared_ptr<Drawing::Data> drawingData;
226 int width = GetData<int>();
227 int height = GetData<int>();
228 int id = GetData<int>();
229
230 RSImage rsImage;
231 rsImage.IsEqual(other);
232 canvas.AttachBrush(brush);
233 rsImage.CanvasDrawImage(canvas, rect, Drawing::SamplingOptions(), isBackground);
234 canvas.DetachBrush();
235 rsImage.SetImage(image);
236 rsImage.SetDstRect(dstRect);
237 rsImage.SetImageFit(fitNum);
238 rsImage.SetImageRepeat(repeatNum);
239 rsImage.SetRadius(radius);
240 rsImage.SetScale(scale);
241 rsImage.SetCompressData(drawingData, id, width, height);
242 return true;
243 }
244
RSMaskFuzzTest(const uint8_t * data,size_t size)245 bool RSMaskFuzzTest(const uint8_t* data, size_t size)
246 {
247 if (data == nullptr) {
248 return false;
249 }
250
251 // initialize
252 g_data = data;
253 g_size = size;
254 g_pos = 0;
255
256 double x = GetData<double>();
257 double y = GetData<double>();
258 double scaleX = GetData<double>();
259 double scaleY = GetData<double>();
260 Drawing::Path path;
261 Drawing::Brush brush;
262 sk_sp<SkSVGDOM> svgDom;
263 MaskType type = GetData<MaskType>();
264
265 RSMask rsMask;
266 rsMask.SetSvgX(x);
267 rsMask.SetSvgY(y);
268 rsMask.SetScaleX(scaleX);
269 rsMask.SetScaleY(scaleY);
270 rsMask.SetMaskPath(path);
271 rsMask.SetMaskBrush(brush);
272 rsMask.SetSvgDom(svgDom);
273 rsMask.SetMaskType(type);
274
275 return true;
276 }
277
RSPathFuzzTest(const uint8_t * data,size_t size)278 bool RSPathFuzzTest(const uint8_t* data, size_t size)
279 {
280 if (data == nullptr) {
281 return false;
282 }
283 // initialize
284 g_data = data;
285 g_size = size;
286 g_pos = 0;
287
288 Drawing::Path drPath = Drawing::Path();
289 // std::string path = GetStringFromData(STR_LEN);
290 float distance = GetData<float>();
291 float x = GetData<float>();
292 float y = GetData<float>();
293 Vector2f pos = Vector2f(x, y);
294 float degrees = GetData<float>();
295 std::shared_ptr<RSPath> rsPath1 = RSPath::CreateRSPath();
296
297 rsPath1->GetPosTan(distance, pos, degrees);
298 rsPath1->SetDrawingPath(drPath);
299
300 return true;
301 }
302
RSShaderFuzzTest(const uint8_t * data,size_t size)303 bool RSShaderFuzzTest(const uint8_t* data, size_t size)
304 {
305 if (data == nullptr) {
306 return false;
307 }
308 // initialize
309 g_data = data;
310 g_size = size;
311 g_pos = 0;
312
313 std::shared_ptr<RSShader> shaderPtr = RSShader::CreateRSShader();
314 std::shared_ptr<Drawing::ShaderEffect> shader;
315 shaderPtr->SetDrawingShader(shader);
316
317 return true;
318 }
319
RSShadowFuzzTest(const uint8_t * data,size_t size)320 bool RSShadowFuzzTest(const uint8_t* data, size_t size)
321 {
322 if (data == nullptr) {
323 return false;
324 }
325 // initialize
326 g_data = data;
327 g_size = size;
328 g_pos = 0;
329
330 uint32_t rgba = GetData<uint32_t>();
331 Color color = Color(rgba);
332 float offsetX = GetData<float>();
333 float offsetY = GetData<float>();
334 float alpha = GetData<float>();
335 float elevation = GetData<float>();
336 float radius = GetData<float>();
337 std::shared_ptr<RSPath> path = std::make_shared<RSPath>();
338
339 RSShadow shadow = RSShadow();
340 shadow.SetColor(color);
341 shadow.SetOffsetX(offsetX);
342 shadow.SetOffsetY(offsetY);
343 shadow.SetAlpha(alpha);
344 shadow.SetElevation(elevation);
345 shadow.SetRadius(radius);
346 shadow.SetPath(path);
347
348 return true;
349 }
350
351 } // namespace Rosen
352 } // namespace OHOS
353
354 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)355 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
356 {
357 /* Run your code on data */
358 OHOS::Rosen::RSBlurFilterFuzzTest(data, size);
359 OHOS::Rosen::RSBorderFuzzTest(data, size);
360 OHOS::Rosen::RSImageCacheFuzzTest(data, size);
361 OHOS::Rosen::RSImageFuzzTest(data, size);
362 OHOS::Rosen::RSMaskFuzzTest(data, size);
363 OHOS::Rosen::RSPathFuzzTest(data, size);
364 OHOS::Rosen::RSShaderFuzzTest(data, size);
365 OHOS::Rosen::RSShadowFuzzTest(data, size);
366 return 0;
367 }
368