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 "screen_fuzzer.h"
17
18 #include <iostream>
19 #include <securec.h>
20
21 #include "display_manager.h"
22 #include "display.h"
23 #include "dm_common.h"
24 #include "screen.h"
25 #include "screen_info.h"
26 #include "screen_manager.h"
27
28 namespace OHOS::Rosen {
29
30 namespace {
31 constexpr char END_CHAR = '\0';
32 constexpr size_t LEN = 10;
33 }
34 template<class T>
GetObject(T & object,const uint8_t * data,size_t size)35 size_t GetObject(T &object, const uint8_t *data, size_t size)
36 {
37 size_t objectSize = sizeof(object);
38 if (objectSize > size) {
39 return 0;
40 }
41 return memcpy_s(&object, objectSize, data, objectSize) == EOK ? objectSize : 0;
42 }
43
CreateScreenInfo(const uint8_t * data,size_t size)44 sptr<ScreenInfo> CreateScreenInfo(const uint8_t *data, size_t size)
45 {
46 sptr<ScreenInfo> info = new(std::nothrow) ScreenInfo();
47 if (info == nullptr) {
48 return nullptr;
49 }
50 size_t startPos = 0;
51 char name[LEN + 1];
52 name[LEN] = END_CHAR;
53 for (size_t i = 0; i < LEN; i++) {
54 startPos += GetObject<char>(name[i], data + startPos, size - startPos);
55 }
56 std::string windowName(name);
57 info->name_ = windowName;
58 startPos += GetObject<ScreenId>(info->id_, data + startPos, size - startPos);
59 startPos += GetObject<uint32_t>(info->virtualWidth_, data + startPos, size - startPos);
60 startPos += GetObject<uint32_t>(info->virtualHeight_, data + startPos, size - startPos);
61 startPos += GetObject<float>(info->virtualPixelRatio_, data + startPos, size - startPos);
62 startPos += GetObject<ScreenId>(info->lastParent_, data + startPos, size - startPos);
63 startPos += GetObject<ScreenId>(info->parent_, data + startPos, size - startPos);
64 startPos += GetObject<bool>(info->isScreenGroup_, data + startPos, size - startPos);
65 startPos += GetObject<Rotation>(info->rotation_, data + startPos, size - startPos);
66 startPos += GetObject<Orientation>(info->orientation_, data + startPos, size - startPos);
67 startPos += GetObject<ScreenType>(info->type_, data + startPos, size - startPos);
68 GetObject<uint32_t>(info->modeId_, data + startPos, size - startPos);
69 return info;
70 }
ScreenFuzzTest(sptr<Screen> screen,sptr<Display> display,const uint8_t * data,size_t size)71 bool ScreenFuzzTest(sptr<Screen> screen, sptr<Display> display, const uint8_t *data, size_t size)
72 {
73 if (screen == nullptr || display == nullptr) {
74 return false;
75 }
76 uint32_t modeId;
77 Orientation orientation;
78 size_t minSize = sizeof(modeId) + sizeof(orientation);
79 if (data == nullptr || size < minSize) {
80 return false;
81 }
82 size_t startPos = 0;
83 uint32_t originalDensityDpi = static_cast<uint32_t>(display->GetVirtualPixelRatio() * DOT_PER_INCH);
84 uint32_t modifiedDensityDpi = static_cast<uint32_t>(
85 originalDensityDpi + 80 >= 640 ? originalDensityDpi - 80 : originalDensityDpi + 80);
86 startPos += GetObject<uint32_t>(modeId, data + startPos, size - startPos);
87 GetObject<Orientation>(orientation, data + startPos, size - startPos);
88 screen->SetScreenActiveMode(modeId);
89 screen->SetOrientation(orientation);
90 screen->SetDensityDpi(modifiedDensityDpi);
91 screen->SetScreenActiveMode(0);
92 screen->SetOrientation(Orientation::UNSPECIFIED);
93 screen->SetDensityDpi(originalDensityDpi);
94 return true;
95 }
96
ScreenFuzzTestNoDisplay(sptr<Screen> screen,const uint8_t * data,size_t size)97 bool ScreenFuzzTestNoDisplay(sptr<Screen> screen, const uint8_t *data, size_t size)
98 {
99 if (screen == nullptr) {
100 return false;
101 }
102 uint32_t modeId;
103 Orientation orientation;
104 uint32_t originalDensityDpi = 0;
105 uint32_t modifiedDensityDpi = 0;
106 size_t minSize = sizeof(modeId) + sizeof(orientation) + sizeof(originalDensityDpi) +
107 sizeof(modifiedDensityDpi);
108 if (data == nullptr || size < minSize) {
109 return false;
110 }
111 size_t startPos = 0;
112 GetObject<uint32_t>(originalDensityDpi, data + startPos, size - startPos);
113 GetObject<uint32_t>(modifiedDensityDpi, data + startPos, size - startPos);
114 startPos += GetObject<uint32_t>(modeId, data + startPos, size - startPos);
115 GetObject<Orientation>(orientation, data + startPos, size - startPos);
116 screen->SetScreenActiveMode(modeId);
117 screen->SetOrientation(orientation);
118 screen->SetDensityDpi(modifiedDensityDpi);
119 screen->SetScreenActiveMode(0);
120 screen->SetOrientation(Orientation::UNSPECIFIED);
121 screen->SetDensityDpi(originalDensityDpi);
122 return true;
123 }
124
ColorGamutsFuzzTest(sptr<Screen> screen,const uint8_t * data,size_t size)125 bool ColorGamutsFuzzTest(sptr<Screen> screen, const uint8_t *data, size_t size)
126 {
127 if (screen == nullptr) {
128 return false;
129 }
130 int32_t colorGamutIdx;
131 uint32_t gamutMap;
132 if (data == nullptr || size < sizeof(colorGamutIdx) + sizeof(gamutMap)) {
133 return false;
134 }
135 size_t startPos = 0;
136 startPos += GetObject<int32_t>(colorGamutIdx, data + startPos, size - startPos);
137 GetObject<uint32_t>(gamutMap, data + startPos, size - startPos);
138 std::vector<ScreenColorGamut> colorGamuts;
139 screen->GetScreenSupportedColorGamuts(colorGamuts);
140 size_t colorGamutsSize = colorGamuts.size();
141
142 int32_t index = colorGamutIdx % colorGamutsSize;
143 screen->SetScreenColorGamut(index);
144 ScreenColorGamut colorGamut;
145 screen->GetScreenColorGamut(colorGamut);
146 // It is necessary to judge whether colorGamuts[index] and colorGamut are equal.
147 screen->SetScreenGamutMap(static_cast<ScreenGamutMap>(gamutMap));
148 ScreenGamutMap screenGamutMap;
149 screen->GetScreenGamutMap(screenGamutMap);
150 // It is necessary to judge whether gamutMap and screenGamutMap are equal.
151 return true;
152 }
153
DoMyFuzzTest(const uint8_t * data,size_t size)154 void DoMyFuzzTest(const uint8_t* data, size_t size)
155 {
156 DisplayManager& displayManager = DisplayManager::GetInstance();
157 sptr<Display> display = displayManager.GetDefaultDisplay();
158
159 sptr<Screen> screen = nullptr;
160 if (display != nullptr) {
161 ScreenId screenId = display->GetScreenId();
162 screen = ScreenManager::GetInstance().GetScreenById(screenId);
163 } else {
164 sptr<ScreenInfo> info = CreateScreenInfo(data, size);
165 screen = new (std::nothrow) Screen(info);
166 }
167 if (display == nullptr) {
168 ScreenFuzzTestNoDisplay(screen, data, size);
169 } else {
170 ScreenFuzzTest(screen, display, data, size);
171 }
172 ColorGamutsFuzzTest(screen, data, size);
173 }
174
175 } // namespace.OHOS::Rosen
176
177 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)178 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
179 {
180 /* Run your code on data */
181 OHOS::Rosen::DoMyFuzzTest(data, size);
182 return 0;
183 }
184
185