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#undef private
20
21#include "inputmethodcontroller_fuzzer.h"
22
23#include <cstddef>
24#include <cstdint>
25
26#include "global.h"
27#include "input_attribute.h"
28#include "key_event.h"
29#include "message_parcel.h"
30#include "text_listener.h"
31
32using namespace OHOS::MiscServices;
33namespace OHOS {
34void TestListInputMethod(sptr<InputMethodController> imc)
35{
36    std::vector<Property> properties = {};
37    imc->ListInputMethod(properties);
38    imc->ListInputMethod(false, properties);
39    imc->ListInputMethod(true, properties);
40    imc->DisplayOptionalInputMethod();
41}
42
43void TestListInputMethodSubtype(sptr<InputMethodController> imc, const std::string &fuzzedString, uint32_t fuzzedUint32)
44{
45    std::vector<SubProperty> subProperties = {};
46    Property property;
47    property.name = fuzzedString;
48    property.id = fuzzedString;
49    property.label = fuzzedString;
50    property.icon = fuzzedString;
51    property.iconId = fuzzedUint32;
52    imc->ListInputMethodSubtype(property, subProperties);
53}
54
55void TestDispatchKeyEvent(sptr<InputMethodController> imc, int32_t fuzzedInt32)
56{
57    sptr<OnTextChangedListener> textListener = new TextListener();
58    imc->Attach(textListener);
59
60    std::shared_ptr<MMI::KeyEvent> keyEvent = MMI::KeyEvent::Create();
61    keyEvent->SetKeyAction(fuzzedInt32);
62    keyEvent->SetKeyCode(fuzzedInt32);
63    imc->DispatchKeyEvent(keyEvent, [](std::shared_ptr<MMI::KeyEvent> &keyEvent, bool isConsumed) {});
64}
65
66void TestOnSelectionChange(sptr<InputMethodController> imc, std::u16string fuzzedU16String, int fuzzedInt,
67    double fuzzedDouble)
68{
69    sptr<OnTextChangedListener> textListener = new TextListener();
70    imc->Attach(textListener);
71
72    CursorInfo cursorInfo;
73    cursorInfo.height = fuzzedDouble;
74    cursorInfo.left = fuzzedDouble;
75    cursorInfo.top = fuzzedDouble;
76    cursorInfo.width = fuzzedDouble;
77    imc->OnCursorUpdate(cursorInfo);
78
79    imc->OnSelectionChange(fuzzedU16String, fuzzedInt, fuzzedInt);
80}
81
82void TestOnConfigurationChange(sptr<InputMethodController> imc)
83{
84    sptr<OnTextChangedListener> textListener = new TextListener();
85    imc->Attach(textListener);
86
87    Configuration info;
88    EnterKeyType keyType = EnterKeyType::DONE;
89    info.SetEnterKeyType(keyType);
90    TextInputType textInputType = TextInputType::DATETIME;
91    info.SetTextInputType(textInputType);
92    imc->OnConfigurationChange(info);
93    int32_t enterKeyType;
94    int32_t inputPattern;
95    imc->GetEnterKeyType(enterKeyType);
96    imc->GetInputPattern(inputPattern);
97}
98
99void TestSwitchInputMethod(SwitchTrigger fuzzedTrigger, sptr<InputMethodController> imc,
100    const std::string &fuzzedString)
101{
102    imc->SwitchInputMethod(fuzzedTrigger, fuzzedString, fuzzedString);
103    imc->ShowOptionalInputMethod();
104}
105
106void TestSetCallingWindow(sptr<InputMethodController> imc, uint32_t fuzzedUInt32)
107{
108    sptr<OnTextChangedListener> textListener = new TextListener();
109    imc->Attach(textListener);
110
111    imc->SetCallingWindow(fuzzedUInt32);
112    imc->ShowSoftKeyboard();
113    imc->HideSoftKeyboard();
114}
115
116void TestShowSomething(sptr<InputMethodController> imc)
117{
118    sptr<OnTextChangedListener> textListener = new TextListener();
119    imc->Attach(textListener);
120    imc->ShowCurrentInput();
121    imc->HideCurrentInput();
122
123    imc->ShowTextInput();
124    imc->HideTextInput();
125
126    imc->GetCurrentInputMethod();
127    imc->GetCurrentInputMethodSubtype();
128
129    imc->StopInputSession();
130    imc->Close();
131}
132
133void TestUpdateListenEventFlag(sptr<InputMethodController> imc, uint32_t fuzzedUint32)
134{
135    imc->UpdateListenEventFlag(static_cast<uint32_t>(fuzzedUint32), static_cast<uint32_t>(fuzzedUint32), true);
136    imc->UpdateListenEventFlag(static_cast<uint32_t>(fuzzedUint32), static_cast<uint32_t>(fuzzedUint32), false);
137}
138
139void TestAttach(sptr<InputMethodController> imc, int32_t fuzzedInt32)
140{
141    sptr<OnTextChangedListener> textListener = new TextListener();
142    InputAttribute inputAttribute;
143    inputAttribute.inputPattern = fuzzedInt32;
144    inputAttribute.enterKeyType = fuzzedInt32;
145    inputAttribute.inputOption = fuzzedInt32;
146    imc->Attach(textListener, true, inputAttribute);
147    imc->Attach(textListener, false, inputAttribute);
148}
149
150void FUZZHideInput(sptr<InputMethodController> imc)
151{
152    sptr<IInputClient> client = new (std::nothrow) InputClientStub();
153    imc->HideInput(client);
154    imc->RequestHideInput();
155}
156
157void FUZZShowInput(sptr<InputMethodController> imc)
158{
159    sptr<IInputClient> client = new (std::nothrow) InputClientStub();
160    imc->ShowInput(client);
161    imc->RequestShowInput();
162}
163
164void FUZZRestore(sptr<InputMethodController> imc)
165{
166    imc->RestoreListenEventFlag();
167    imc->RestoreListenInfoInSaDied();
168    imc->RestoreAttachInfoInSaDied();
169}
170
171void InputType(sptr<InputMethodController> imc)
172{
173    imc->IsInputTypeSupported(InputType::CAMERA_INPUT);
174    imc->IsInputTypeSupported(InputType::SECURITY_INPUT);
175    imc->StartInputType(InputType::CAMERA_INPUT);
176    imc->StartInputType(InputType::SECURITY_INPUT);
177}
178
179void FUZZIsPanelShown(sptr<InputMethodController> imc, const uint8_t *data)
180{
181    PanelInfo panelInfo = { .panelType = SOFT_KEYBOARD, .panelFlag = FLG_FIXED };
182    bool flag = static_cast<bool>(data[0] % 2);
183    imc->IsPanelShown(panelInfo, flag);
184}
185
186void FUZZPrintLogIfAceTimeout(sptr<InputMethodController> imc, int64_t start)
187{
188    imc->PrintLogIfAceTimeout(start);
189}
190} // namespace OHOS
191
192/* Fuzzer entry point */
193extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
194{
195    /* Run your code on data */
196    std::string fuzzedString(data, data + size);
197    std::u16string fuzzedU16String = u"insert text";
198
199    auto fuzzedInt = static_cast<int>(size);
200    auto fuzzedInt32 = static_cast<int32_t>(size);
201    auto fuzzedUint32 = static_cast<uint32_t>(size);
202    auto fuzzedint64 = static_cast<int64_t>(size);
203    auto fuzzedDouble = static_cast<double>(size);
204    auto fuzzedTrigger = static_cast<SwitchTrigger>(size);
205
206    OHOS::sptr<InputMethodController> imc = InputMethodController::GetInstance();
207
208    OHOS::TestListInputMethod(imc);
209    OHOS::TestListInputMethodSubtype(imc, fuzzedString, fuzzedUint32);
210    OHOS::TestOnSelectionChange(imc, fuzzedU16String, fuzzedInt, fuzzedDouble);
211    OHOS::TestOnConfigurationChange(imc);
212    OHOS::TestSwitchInputMethod(fuzzedTrigger, imc, fuzzedString);
213    OHOS::TestSetCallingWindow(imc, fuzzedUint32);
214    OHOS::TestDispatchKeyEvent(imc, fuzzedInt32);
215    OHOS::TestShowSomething(imc);
216    OHOS::FUZZHideInput(imc);
217    OHOS::FUZZShowInput(imc);
218    OHOS::FUZZRestore(imc);
219    OHOS::InputType(imc);
220    OHOS::FUZZIsPanelShown(imc, data);
221    OHOS::FUZZPrintLogIfAceTimeout(imc, fuzzedint64);
222    OHOS::TestUpdateListenEventFlag(imc, fuzzedUint32);
223    return 0;
224}
225