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