1 /*
2 * Copyright (c) 2024 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 <cstddef>
17 #include <cstdint>
18 #include <iostream>
19
20 #include "wantparamsfifth_fuzzer.h"
21
22 #define private public
23 #include "want_params.h"
24 #undef private
25 #include "array_wrapper.h"
26 #include "base_interfaces.h"
27 #include "bool_wrapper.h"
28 #include "byte_wrapper.h"
29 #include "double_wrapper.h"
30 #include "float_wrapper.h"
31 #include "int_wrapper.h"
32 #include "long_wrapper.h"
33 #include "remote_object_wrapper.h"
34 #include "securec.h"
35 #include "short_wrapper.h"
36 #include "string_wrapper.h"
37 #include "want_params_wrapper.h"
38 #include "zchar_wrapper.h"
39
40 using namespace OHOS::AAFwk;
41
42 namespace OHOS {
43 namespace {
44 constexpr size_t U32_AT_SIZE = 4;
45 constexpr size_t PARAMS_SIZE = 21;
46 constexpr int32_t OTHER = -2;
47 constexpr int32_t ARRAY_SIZE = 5;
48 } // namespace
49
GetU32Data(const char * ptr)50 uint32_t GetU32Data(const char* ptr)
51 {
52 // convert fuzz input data to an integer
53 return (ptr[0] << 24) | (ptr[1] << 16) | (ptr[2] << 8) | ptr[3];
54 }
55
WriteBasicTypesToParcel(Parcel & parcel,const char * data,size_t size)56 void WriteBasicTypesToParcel(Parcel& parcel, const char* data, size_t size)
57 {
58 std::string stringValue(data, size);
59 bool boolValue = static_cast<bool>(GetU32Data(data));
60 int8_t byteValue = static_cast<int8_t>(GetU32Data(data));
61 char charValue = static_cast<char>(GetU32Data(data));
62 int16_t shortValue = static_cast<int16_t>(GetU32Data(data));
63 int32_t intValue = static_cast<int32_t>(GetU32Data(data));
64 long longValue = static_cast<long>(GetU32Data(data));
65 float floatValue = static_cast<float>(GetU32Data(data));
66 double doubleValue = static_cast<double>(GetU32Data(data));
67
68 parcel.WriteInt32(PARAMS_SIZE);
69 parcel.WriteString16(Str8ToStr16("booleanKey"));
70 parcel.WriteInt32(WantParams::VALUE_TYPE_BOOLEAN);
71 parcel.WriteBool(boolValue);
72 parcel.WriteString16(Str8ToStr16("byteKey"));
73 parcel.WriteInt32(WantParams::VALUE_TYPE_BYTE);
74 parcel.WriteInt8(byteValue);
75 parcel.WriteString16(Str8ToStr16("charKey"));
76 parcel.WriteInt32(WantParams::VALUE_TYPE_CHAR);
77 parcel.WriteInt32(charValue);
78 parcel.WriteString16(Str8ToStr16("shortKey"));
79 parcel.WriteInt32(WantParams::VALUE_TYPE_SHORT);
80 parcel.WriteInt16(shortValue);
81 parcel.WriteString16(Str8ToStr16("intKey"));
82 parcel.WriteInt32(WantParams::VALUE_TYPE_INT);
83 parcel.WriteInt32(intValue);
84 parcel.WriteString16(Str8ToStr16("longKey"));
85 parcel.WriteInt32(WantParams::VALUE_TYPE_LONG);
86 parcel.WriteInt64(longValue);
87 parcel.WriteString16(Str8ToStr16("floatKey"));
88 parcel.WriteInt32(WantParams::VALUE_TYPE_FLOAT);
89 parcel.WriteFloat(floatValue);
90 parcel.WriteString16(Str8ToStr16("doubleKey"));
91 parcel.WriteInt32(WantParams::VALUE_TYPE_DOUBLE);
92 parcel.WriteDouble(doubleValue);
93 parcel.WriteString16(Str8ToStr16("stringKey"));
94 parcel.WriteInt32(WantParams::VALUE_TYPE_STRING);
95 parcel.WriteString16(Str8ToStr16(stringValue));
96 }
97
WriteArrayToParcel(Parcel & parcel,const std::string & key,int32_t type,sptr<IArray> array,std::shared_ptr<WantParams> wantParams)98 void WriteArrayToParcel(
99 Parcel& parcel, const std::string& key, int32_t type, sptr<IArray> array, std::shared_ptr<WantParams> wantParams)
100 {
101 parcel.WriteString16(Str8ToStr16(key));
102 parcel.WriteInt32(type);
103 wantParams->WriteArrayToParcel(parcel, array, 0);
104 }
105
WriteArraysToParcel(Parcel & parcel,const char * data,size_t size,std::shared_ptr<WantParams> wantParams)106 void WriteArraysToParcel(Parcel& parcel, const char* data, size_t size, std::shared_ptr<WantParams> wantParams)
107 {
108 std::string stringValue(data, size);
109 sptr<IArray> booleanArray = new Array(ARRAY_SIZE, g_IID_IBoolean);
110 sptr<IArray> charArray = new Array(ARRAY_SIZE, g_IID_IChar);
111 sptr<IArray> byteArray = new Array(ARRAY_SIZE, g_IID_IByte);
112 sptr<IArray> shortArray = new Array(ARRAY_SIZE, g_IID_IShort);
113 sptr<IArray> integerArray = new Array(ARRAY_SIZE, g_IID_IInteger);
114 sptr<IArray> longArray = new Array(ARRAY_SIZE, g_IID_ILong);
115 sptr<IArray> floatArray = new Array(ARRAY_SIZE, g_IID_IFloat);
116 sptr<IArray> doubleArray = new Array(ARRAY_SIZE, g_IID_IDouble);
117 sptr<IArray> stringArray = new Array(ARRAY_SIZE, g_IID_IString);
118 sptr<IArray> wantParamsArray = new Array(ARRAY_SIZE, g_IID_IWantParams);
119 sptr<IArray> other = new Array(ARRAY_SIZE, g_IID_IRemoteObjectWrap);
120 for (int32_t i = 0; i < ARRAY_SIZE; i++) {
121 booleanArray->Set(i, Boolean::Box(static_cast<bool>(GetU32Data(data))));
122 charArray->Set(i, Char::Box(static_cast<char>(GetU32Data(data))));
123 byteArray->Set(i, Byte::Box(static_cast<int8_t>(GetU32Data(data))));
124 shortArray->Set(i, Short::Box(static_cast<int16_t>(GetU32Data(data))));
125 integerArray->Set(i, Integer::Box(static_cast<int32_t>(GetU32Data(data))));
126 longArray->Set(i, Long::Box(static_cast<long>(GetU32Data(data))));
127 floatArray->Set(i, Float::Box(static_cast<float>(GetU32Data(data))));
128 doubleArray->Set(i, Double::Box(static_cast<double>(GetU32Data(data))));
129 stringArray->Set(i, String::Box(stringValue));
130 other->Set(i, RemoteObjectWrap::Box(nullptr));
131 }
132 WriteArrayToParcel(parcel, "stringArray", WantParams::VALUE_TYPE_STRINGARRAY, stringArray, wantParams);
133 WriteArrayToParcel(parcel, "booleanArray", WantParams::VALUE_TYPE_BOOLEANARRAY, booleanArray, wantParams);
134 WriteArrayToParcel(parcel, "byteArray", WantParams::VALUE_TYPE_BYTEARRAY, byteArray, wantParams);
135 WriteArrayToParcel(parcel, "charArray", WantParams::VALUE_TYPE_CHARARRAY, charArray, wantParams);
136 WriteArrayToParcel(parcel, "shortArray", WantParams::VALUE_TYPE_SHORTARRAY, shortArray, wantParams);
137 WriteArrayToParcel(parcel, "integerArray", WantParams::VALUE_TYPE_INTARRAY, integerArray, wantParams);
138 WriteArrayToParcel(parcel, "longArray", WantParams::VALUE_TYPE_LONGARRAY, longArray, wantParams);
139 WriteArrayToParcel(parcel, "floatArray", WantParams::VALUE_TYPE_FLOATARRAY, floatArray, wantParams);
140 WriteArrayToParcel(parcel, "doubleArray", WantParams::VALUE_TYPE_DOUBLEARRAY, doubleArray, wantParams);
141 WriteArrayToParcel(parcel, "wantParamsArray", WantParams::VALUE_TYPE_WANTPARAMSARRAY, wantParamsArray, wantParams);
142 WriteArrayToParcel(parcel, "other", OTHER, other, wantParams);
143 parcel.WriteInt32(WantParams::VALUE_TYPE_NULL);
144 }
145
DoSomethingInterestingWithMyAPI(const char * data,size_t size)146 bool DoSomethingInterestingWithMyAPI(const char* data, size_t size)
147 {
148 WantParams wantOther;
149 std::shared_ptr<WantParams> wantParams = std::make_shared<WantParams>(wantOther);
150
151 Parcel parcel;
152 WriteBasicTypesToParcel(parcel, data, size);
153 WriteArraysToParcel(parcel, data, size, wantParams);
154
155 auto wantPtr = wantParams->Unmarshalling(parcel, 0);
156 if (wantPtr) {
157 delete wantPtr;
158 wantPtr = nullptr;
159 }
160 return true;
161 }
162 } // namespace OHOS
163
164 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)165 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
166 {
167 /* Run your code on data */
168 if (data == nullptr) {
169 std::cout << "invalid data" << std::endl;
170 return 0;
171 }
172
173 /* Validate the length of size */
174 if (size < OHOS::U32_AT_SIZE) {
175 return 0;
176 }
177
178 char* ch = (char*)malloc(size + 1);
179 if (ch == nullptr) {
180 std::cout << "malloc failed." << std::endl;
181 return 0;
182 }
183
184 (void)memset_s(ch, size + 1, 0x00, size + 1);
185 if (memcpy_s(ch, size, data, size) != EOK) {
186 std::cout << "copy failed." << std::endl;
187 free(ch);
188 ch = nullptr;
189 return 0;
190 }
191
192 OHOS::DoSomethingInterestingWithMyAPI(ch, size);
193 free(ch);
194 ch = nullptr;
195 return 0;
196 }
197