1 /*
2 * Copyright (c) 2022-2023 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 #define private public
16 #define protected public
17 #include "input_method_controller.h"
18 #include "input_method_system_ability_proxy.h"
19 #include "input_client_service_impl.h"
20 #undef private
21
22 #include "inputmethodcontroller_fuzzer.h"
23
24 #include <cstddef>
25 #include <cstdint>
26
27 #include "fuzzer/FuzzedDataProvider.h"
28 #include "global.h"
29 #include "input_attribute.h"
30 #include "key_event.h"
31 #include "message_parcel.h"
32 #include "text_listener.h"
33
34 using namespace OHOS::MiscServices;
35 namespace OHOS {
36 class EventHandlerTextListenerImpl : public TextListener {
37 public:
EventHandlerTextListenerImpl(const std::shared_ptr<AppExecFwk::EventHandler> & handler)38 explicit EventHandlerTextListenerImpl(const std::shared_ptr<AppExecFwk::EventHandler> &handler)
39 {
40 listenerEventHandler_ = handler;
41 }
GetEventHandler()42 std::shared_ptr<AppExecFwk::EventHandler> GetEventHandler()
43 {
44 return listenerEventHandler_;
45 }
46
47 private:
48 std::shared_ptr<AppExecFwk::EventHandler> listenerEventHandler_{ nullptr };
49 };
50 constexpr int32_t PRIVATEDATAVALUE = 100;
TestListInputMethod(sptr<InputMethodController> imc)51 void TestListInputMethod(sptr<InputMethodController> imc)
52 {
53 std::vector<Property> properties = {};
54 imc->ListInputMethod(properties);
55 imc->ListInputMethod(false, properties);
56 imc->ListInputMethod(true, properties);
57 imc->DisplayOptionalInputMethod();
58 }
59
TestListInputMethodSubtype(sptr<InputMethodController> imc,const std::string & fuzzedString,uint32_t fuzzedUint32)60 void TestListInputMethodSubtype(sptr<InputMethodController> imc, const std::string &fuzzedString, uint32_t fuzzedUint32)
61 {
62 std::vector<SubProperty> subProperties = {};
63 Property property;
64 property.name = fuzzedString;
65 property.id = fuzzedString;
66 property.label = fuzzedString;
67 property.icon = fuzzedString;
68 property.iconId = fuzzedUint32;
69 imc->ListInputMethodSubtype(property, subProperties);
70 }
71
TestDispatchKeyEvent(sptr<InputMethodController> imc,int32_t fuzzedInt32)72 void TestDispatchKeyEvent(sptr<InputMethodController> imc, int32_t fuzzedInt32)
73 {
74 sptr<OnTextChangedListener> textListener = new TextListener();
75 if (textListener == nullptr) {
76 return;
77 }
78 imc->Attach(textListener);
79 imc->isBound_.store(true);
80
81 std::shared_ptr<MMI::KeyEvent> keyEvent = MMI::KeyEvent::Create();
82 if (keyEvent == nullptr) {
83 return;
84 }
85 keyEvent->SetKeyAction(fuzzedInt32);
86 keyEvent->SetKeyCode(fuzzedInt32);
87 imc->DispatchKeyEvent(keyEvent, [](std::shared_ptr<MMI::KeyEvent> &keyEvent, bool isConsumed) {});
88 }
89
TestOnSelectionChange(sptr<InputMethodController> imc,std::u16string fuzzedU16String,int fuzzedInt,double fuzzedDouble)90 void TestOnSelectionChange(sptr<InputMethodController> imc, std::u16string fuzzedU16String, int fuzzedInt,
91 double fuzzedDouble)
92 {
93 sptr<OnTextChangedListener> textListener = new TextListener();
94 if (textListener == nullptr) {
95 return;
96 }
97 imc->Attach(textListener);
98 imc->isBound_.store(true);
99
100 CursorInfo cursorInfo;
101 cursorInfo.height = fuzzedDouble;
102 cursorInfo.left = fuzzedDouble;
103 cursorInfo.top = fuzzedDouble;
104 cursorInfo.width = fuzzedDouble;
105 imc->OnCursorUpdate(cursorInfo);
106
107 imc->OnSelectionChange(fuzzedU16String, fuzzedInt, fuzzedInt);
108 }
109
TestOnConfigurationChange(sptr<InputMethodController> imc)110 void TestOnConfigurationChange(sptr<InputMethodController> imc)
111 {
112 sptr<OnTextChangedListener> textListener = new TextListener();
113 if (textListener == nullptr) {
114 return;
115 }
116 imc->Attach(textListener);
117 imc->isBound_.store(true);
118
119 Configuration info;
120 EnterKeyType keyType = EnterKeyType::DONE;
121 info.SetEnterKeyType(keyType);
122 TextInputType textInputType = TextInputType::DATETIME;
123 info.SetTextInputType(textInputType);
124 imc->OnConfigurationChange(info);
125 int32_t enterKeyType;
126 int32_t inputPattern;
127 imc->GetEnterKeyType(enterKeyType);
128 imc->GetInputPattern(inputPattern);
129 }
130
TestSwitchInputMethod(SwitchTrigger fuzzedTrigger,sptr<InputMethodController> imc,const std::string & fuzzedString)131 void TestSwitchInputMethod(SwitchTrigger fuzzedTrigger, sptr<InputMethodController> imc,
132 const std::string &fuzzedString)
133 {
134 imc->SwitchInputMethod(fuzzedTrigger, fuzzedString, fuzzedString);
135 imc->ShowOptionalInputMethod();
136 }
137
TestSetCallingWindow(sptr<InputMethodController> imc,uint32_t fuzzedUInt32)138 void TestSetCallingWindow(sptr<InputMethodController> imc, uint32_t fuzzedUInt32)
139 {
140 sptr<OnTextChangedListener> textListener = new TextListener();
141 if (textListener == nullptr) {
142 return;
143 }
144 imc->Attach(textListener);
145
146 imc->SetCallingWindow(fuzzedUInt32);
147 imc->ShowSoftKeyboard();
148 imc->HideSoftKeyboard();
149 }
150
TestUpdateListenEventFlag(sptr<InputMethodController> imc,uint32_t fuzzedUint32)151 void TestUpdateListenEventFlag(sptr<InputMethodController> imc, uint32_t fuzzedUint32)
152 {
153 imc->UpdateListenEventFlag(static_cast<uint32_t>(fuzzedUint32), static_cast<uint32_t>(fuzzedUint32), true);
154 imc->UpdateListenEventFlag(static_cast<uint32_t>(fuzzedUint32), static_cast<uint32_t>(fuzzedUint32), false);
155 }
156
TestAttach(sptr<InputMethodController> imc,int32_t fuzzedInt32)157 void TestAttach(sptr<InputMethodController> imc, int32_t fuzzedInt32)
158 {
159 sptr<OnTextChangedListener> textListener = new TextListener();
160 if (textListener == nullptr) {
161 return;
162 }
163 InputAttribute inputAttribute;
164 inputAttribute.inputPattern = fuzzedInt32;
165 inputAttribute.enterKeyType = fuzzedInt32;
166 inputAttribute.inputOption = fuzzedInt32;
167 imc->Attach(textListener, true, inputAttribute);
168 imc->Attach(textListener, false, inputAttribute);
169 }
170
FUZZRestore(sptr<InputMethodController> imc)171 void FUZZRestore(sptr<InputMethodController> imc)
172 {
173 imc->RestoreListenEventFlag();
174 imc->RestoreListenInfoInSaDied();
175 imc->RestoreClientInfoInSaDied();
176 }
177
InputType(sptr<InputMethodController> imc)178 void InputType(sptr<InputMethodController> imc)
179 {
180 imc->IsInputTypeSupported(InputType::CAMERA_INPUT);
181 imc->IsInputTypeSupported(InputType::SECURITY_INPUT);
182 imc->StartInputType(InputType::CAMERA_INPUT);
183 imc->StartInputType(InputType::SECURITY_INPUT);
184 }
185
FUZZIsPanelShown(sptr<InputMethodController> imc,const uint8_t * data)186 void FUZZIsPanelShown(sptr<InputMethodController> imc, const uint8_t *data)
187 {
188 PanelInfo panelInfo;
189 panelInfo.panelType = SOFT_KEYBOARD;
190 panelInfo.panelFlag = FLG_FIXED;
191 bool flag = static_cast<bool>(data[0] % 2);
192 imc->IsPanelShown(panelInfo, flag);
193 }
194
FUZZPrintLogIfAceTimeout(sptr<InputMethodController> imc,int64_t start)195 void FUZZPrintLogIfAceTimeout(sptr<InputMethodController> imc, int64_t start)
196 {
197 imc->PrintLogIfAceTimeout(start);
198 }
199
FUZZGetInputStartInfo(sptr<InputMethodController> imc,bool & dataBool,uint32_t & callingWndId,int32_t & int32Value,const std::string & fuzzedString)200 void FUZZGetInputStartInfo(sptr<InputMethodController> imc, bool &dataBool,
201 uint32_t &callingWndId, int32_t &int32Value, const std::string &fuzzedString)
202 {
203 imc->GetInputStartInfo(dataBool, callingWndId, int32Value);
204 imc->EnableIme(fuzzedString);
205 imc->IsCurrentImeByPid(int32Value);
206 imc->UpdateTextPreviewState(dataBool);
207 }
208
FUZZSetControllerListener(sptr<InputMethodController> imc,uint32_t & uint32Value,const std::string & fuzzedString,bool & dataBool)209 void FUZZSetControllerListener(sptr<InputMethodController> imc,
210 uint32_t &uint32Value, const std::string &fuzzedString, bool &dataBool)
211 {
212 sptr<OnTextChangedListener> textListener = new TextListener();
213 if (textListener == nullptr) {
214 return;
215 }
216 imc->Attach(textListener);
217 static std::vector<SubProperty> subProps;
218 static std::shared_ptr<Property> property = std::make_shared<Property>();
219 property->name = fuzzedString;
220 property->id = fuzzedString;
221 property->label = fuzzedString;
222 property->icon = fuzzedString;
223 property->iconId = uint32Value;
224
225 OHOS::AppExecFwk::ElementName inputMethodConfig;
226 inputMethodConfig.SetDeviceID(fuzzedString);
227 inputMethodConfig.SetAbilityName(fuzzedString);
228 inputMethodConfig.SetBundleName(fuzzedString);
229 inputMethodConfig.SetModuleName(fuzzedString);
230 wptr<IRemoteObject> agentObject = nullptr;
231 SubProperty subProperty;
232 subProperty.label = fuzzedString;
233 subProperty.labelId = uint32Value;
234 subProperty.name = fuzzedString;
235 subProperty.id = fuzzedString;
236 subProperty.mode = fuzzedString;
237 subProperty.locale = fuzzedString;
238 subProperty.icon = fuzzedString;
239 subProps.push_back(subProperty);
240 std::unordered_map <std::string, PrivateDataValue> privateCommand;
241 PrivateDataValue privateDataValue1 = fuzzedString;
242 PrivateDataValue privateDataValue2 = static_cast<int32_t>(dataBool);
243 PrivateDataValue privateDataValue3 = PRIVATEDATAVALUE;
244 privateCommand.emplace("value1", privateDataValue1);
245 privateCommand.emplace("value2", privateDataValue2);
246 privateCommand.emplace("value3", privateDataValue3);
247 imc->SetControllerListener(nullptr);
248 imc->DiscardTypingText();
249 imc->GetDefaultInputMethod(property);
250 imc->GetInputMethodConfig(inputMethodConfig);
251 imc->OnRemoteSaDied(agentObject);
252 imc->ListCurrentInputMethodSubtype(subProps);
253 imc->SendPrivateCommand(privateCommand);
254 imc->Reset();
255 imc->IsDefaultImeSet();
256 }
TestShowTextInputInner(sptr<InputMethodController> imc,const uint8_t * data,size_t size)257 void TestShowTextInputInner(sptr<InputMethodController> imc, const uint8_t *data, size_t size)
258 {
259 sptr<OnTextChangedListener> textListener = new TextListener();
260 if (textListener == nullptr) {
261 return;
262 }
263 std::string fuzzedString(reinterpret_cast<const char *>(data), size);
264 auto fuzzedBool = static_cast<bool>(data[0] % 2);
265 std::vector<uint8_t> msgParam;
266 msgParam.push_back(*data);
267 std::unordered_map <std::string, PrivateDataValue> privateCommand;
268 imc->Attach(textListener);
269 AttachOptions attachOptions;
270 attachOptions.isShowKeyboard = fuzzedBool;
271 attachOptions.requestKeyboardReason = RequestKeyboardReason::NONE;
272 ClientType clientType = ClientType::INNER_KIT;
273 imc->ShowTextInputInner(attachOptions, clientType);
274 imc->isEditable_.store(true);
275 imc->SendPrivateData(privateCommand);
276 }
277
FUZZOnTextChangedListener(const uint8_t * data,size_t size)278 void FUZZOnTextChangedListener(const uint8_t *data, size_t size)
279 {
280 std::u16string fuzzedU16String = u"insert text";
281 std::string fuzzedString(reinterpret_cast<const char *>(data), size);
282 auto fuzzInt32 = static_cast<int32_t>(size);
283 auto fuzzBool = static_cast<bool>(data[0] % 2);
284 FunctionKey key;
285 KeyEvent keyEvent;
286 Range range = { .start = fuzzInt32, .end = fuzzInt32};
287 PanelInfo panelInfo;
288 panelInfo.panelType = static_cast<PanelType>(fuzzBool);
289 panelInfo.panelFlag = static_cast<PanelFlag>(fuzzBool);
290 PanelStatusInfo panelStatusInfo;
291 panelStatusInfo.panelInfo = panelInfo;
292 panelStatusInfo.visible = fuzzBool;
293 panelStatusInfo.trigger = Trigger::IME_APP;
294 std::shared_ptr<AppExecFwk::EventRunner> runner = AppExecFwk::EventRunner::Create("eventHandlerTextListener");
295 auto handler = std::make_shared<AppExecFwk::EventHandler>(runner);
296 sptr<OnTextChangedListener> eventHandlerTextListener = new (std::nothrow) EventHandlerTextListenerImpl(handler);
297 if (eventHandlerTextListener == nullptr) {
298 return;
299 }
300 std::unordered_map <std::string, PrivateDataValue> privateCommand;
301 PrivateDataValue privateDataValue1 = fuzzedString;
302 PrivateDataValue privateDataValue2 = static_cast<int32_t>(fuzzBool);
303 PrivateDataValue privateDataValue3 = PRIVATEDATAVALUE;
304 privateCommand.emplace("value1", privateDataValue1);
305 privateCommand.emplace("value2", privateDataValue2);
306 privateCommand.emplace("value3", privateDataValue3);
307 eventHandlerTextListener->InsertTextV2(fuzzedU16String);
308 eventHandlerTextListener->DeleteForwardV2(fuzzInt32);
309 eventHandlerTextListener->DeleteBackwardV2(fuzzInt32);
310 eventHandlerTextListener->SendKeyboardStatusV2(KeyboardStatus::SHOW);
311 eventHandlerTextListener->SendFunctionKeyV2(key);
312 eventHandlerTextListener->MoveCursorV2(Direction::DOWN);
313 eventHandlerTextListener->HandleExtendActionV2(fuzzInt32);
314 eventHandlerTextListener->GetLeftTextOfCursorV2(fuzzInt32);
315 eventHandlerTextListener->GetRightTextOfCursorV2(fuzzInt32);
316 eventHandlerTextListener->GetTextIndexAtCursorV2();
317 eventHandlerTextListener->SendKeyEventFromInputMethodV2(keyEvent);
318 eventHandlerTextListener->SetKeyboardStatusV2(fuzzBool);
319 eventHandlerTextListener->HandleSetSelectionV2(fuzzInt32, fuzzInt32);
320 eventHandlerTextListener->HandleSelectV2(fuzzInt32, fuzzInt32);
321 eventHandlerTextListener->OnDetachV2();
322 eventHandlerTextListener->NotifyPanelStatusInfoV2(panelStatusInfo);
323 eventHandlerTextListener->NotifyKeyboardHeightV2(fuzzInt32);
324 eventHandlerTextListener->ReceivePrivateCommandV2(privateCommand);
325 eventHandlerTextListener->FinishTextPreviewV2();
326 eventHandlerTextListener->SetPreviewTextV2(fuzzedU16String, range);
327 }
328
FUZZCovered(sptr<InputMethodController> imc,const uint8_t * data,size_t size)329 void FUZZCovered(sptr<InputMethodController> imc, const uint8_t *data, size_t size)
330 {
331 std::string fuzzedString(reinterpret_cast<const char *>(data), size);
332 std::vector<uint8_t> msgParam;
333 msgParam.push_back(*data);
334 ArrayBuffer arrayBuffer;
335 arrayBuffer.jsArgc = size;
336 arrayBuffer.msgId = fuzzedString;
337 arrayBuffer.msgParam = msgParam;
338 imc->HideTextInput();
339 imc->GetCurrentInputMethod();
340 imc->GetCurrentInputMethodSubtype();
341 imc->ShowCurrentInput();
342 imc->HideCurrentInput();
343 imc->ShowTextInput();
344 imc->HideTextInput();
345 imc->GetCurrentInputMethod();
346 imc->GetCurrentInputMethodSubtype();
347 imc->SendMessage(arrayBuffer);
348 imc->RecvMessage(arrayBuffer);
349 imc->Close();
350 }
351 } // namespace OHOS
352
353 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)354 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
355 {
356 /* Run your code on data */
357 if (data == nullptr || size == 0) {
358 return 0;
359 }
360 FuzzedDataProvider provider(data, size);
361 std::string fuzzedString(data, data + size);
362 std::u16string fuzzedU16String = u"insert text";
363
364 auto fuzzedInt = provider.ConsumeIntegral<int>();
365 auto fuzzedInt32 = provider.ConsumeIntegral<int32_t>();
366 auto fuzzedUint32 = provider.ConsumeIntegral<uint32_t>();
367 auto fuzzedint64 = provider.ConsumeIntegral<int64_t>();
368 auto fuzzedDouble = static_cast<double>(size);
369 auto fuzzedTrigger = static_cast<SwitchTrigger>(size);
370 auto fuzzedBool = provider.ConsumeBool();
371
372 OHOS::sptr<InputMethodController> imc = InputMethodController::GetInstance();
373
374 OHOS::TestListInputMethod(imc);
375 OHOS::TestListInputMethodSubtype(imc, fuzzedString, fuzzedUint32);
376 OHOS::TestOnSelectionChange(imc, fuzzedU16String, fuzzedInt, fuzzedDouble);
377 OHOS::TestOnConfigurationChange(imc);
378 OHOS::TestSwitchInputMethod(fuzzedTrigger, imc, fuzzedString);
379 OHOS::TestSetCallingWindow(imc, fuzzedUint32);
380 OHOS::TestDispatchKeyEvent(imc, fuzzedInt32);
381 OHOS::FUZZRestore(imc);
382 OHOS::InputType(imc);
383 OHOS::FUZZIsPanelShown(imc, data);
384 OHOS::FUZZPrintLogIfAceTimeout(imc, fuzzedint64);
385 OHOS::TestUpdateListenEventFlag(imc, fuzzedUint32);
386 OHOS::FUZZGetInputStartInfo(imc, fuzzedBool, fuzzedUint32, fuzzedInt32, fuzzedString);
387 OHOS::FUZZSetControllerListener(imc, fuzzedUint32, fuzzedString, fuzzedBool);
388 OHOS::TestShowTextInputInner(imc, data, size);
389 OHOS::FUZZCovered(imc, data, size);
390 return 0;
391 }
392