• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     if (colorGamutsSize == 0) {
142         return false;
143     }
144     int32_t index = colorGamutIdx % colorGamutsSize;
145     screen->SetScreenColorGamut(index);
146     ScreenColorGamut colorGamut;
147     screen->GetScreenColorGamut(colorGamut);
148     // It is necessary to judge whether colorGamuts[index] and colorGamut are equal.
149     screen->SetScreenGamutMap(static_cast<ScreenGamutMap>(gamutMap));
150     ScreenGamutMap screenGamutMap;
151     screen->GetScreenGamutMap(screenGamutMap);
152     // It is necessary to judge whether gamutMap and screenGamutMap are equal.
153     return true;
154 }
155 
DoMyFuzzTest(const uint8_t * data,size_t size)156 void DoMyFuzzTest(const uint8_t* data, size_t size)
157 {
158     DisplayManager& displayManager = DisplayManager::GetInstance();
159     sptr<Display> display = displayManager.GetDefaultDisplay();
160 
161     sptr<Screen> screen = nullptr;
162     if (display != nullptr) {
163         ScreenId screenId = display->GetScreenId();
164         screen = ScreenManager::GetInstance().GetScreenById(screenId);
165     } else {
166         sptr<ScreenInfo> info = CreateScreenInfo(data, size);
167         screen = new (std::nothrow) Screen(info);
168     }
169     if (display == nullptr) {
170         ScreenFuzzTestNoDisplay(screen, data, size);
171     } else {
172         ScreenFuzzTest(screen, display, data, size);
173     }
174     ColorGamutsFuzzTest(screen, data, size);
175 }
176 
177 } // namespace.OHOS::Rosen
178 
179 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)180 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
181 {
182     /* Run your code on data */
183     OHOS::Rosen::DoMyFuzzTest(data, size);
184     return 0;
185 }
186 
187