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 "wantninth_fuzzer.h"
17
18 #include <cstddef>
19 #include <cstdint>
20 #include <iostream>
21
22 #define private public
23 #include "want.h"
24 #undef private
25 #include "array_wrapper.h"
26 #include "bool_wrapper.h"
27 #include "byte_wrapper.h"
28 #include "double_wrapper.h"
29 #include "float_wrapper.h"
30 #include "int_wrapper.h"
31 #include "long_wrapper.h"
32 #include "securec.h"
33 #include "short_wrapper.h"
34 #include "string_wrapper.h"
35 #include "uri.h"
36 #include "zchar_wrapper.h"
37
38 using namespace OHOS::AAFwk;
39
40 namespace OHOS {
41 namespace {
42 constexpr size_t FOO_MAX_LEN = 1024;
43 constexpr size_t U32_AT_SIZE = 4;
44 const uint32_t BYTE0_SHIFT = 24;
45 const uint32_t BYTE1_SHIFT = 16;
46 const uint32_t BYTE2_SHIFT = 8;
47 } // namespace
GetU32Data(const char * ptr,size_t size)48 uint32_t GetU32Data(const char* ptr, size_t size)
49 {
50 if (ptr == nullptr || size > OHOS::FOO_MAX_LEN || size < OHOS::U32_AT_SIZE) {
51 return 0;
52 }
53 return (static_cast<uint32_t>(ptr[0]) << BYTE0_SHIFT) | (static_cast<uint32_t>(ptr[1]) << BYTE1_SHIFT) |
54 (static_cast<uint32_t>(ptr[2]) << BYTE2_SHIFT) | static_cast<uint32_t>(ptr[3]);
55 }
56
57 template <typename T>
GetData(const char * ptr,size_t size)58 typename std::enable_if<std::is_arithmetic<T>::value, T>::type GetData(const char* ptr, size_t size)
59 {
60 if (ptr == nullptr || size > OHOS::FOO_MAX_LEN || size < sizeof(T)) {
61 return static_cast<T>(0);
62 }
63
64 T result = 0;
65 if (memcpy_s(&result, sizeof(T), ptr, std::min(sizeof(T), size)) != 0) {
66 std::cout << "copy failed." << std::endl;
67 return static_cast<T>(0);
68 }
69 return result;
70 }
71
DoFromString(const char * data,size_t size)72 void DoFromString(const char* data, size_t size)
73 {
74 std::shared_ptr<Want> want = std::make_shared<Want>();
75 std::string emptyString;
76 want->FromString(emptyString);
77 std::string values(data, size);
78 want->FromString(values);
79 std::string jsonWant = want->ToString();
80 want->FromString(jsonWant);
81 }
82
DoCheckUri(const char * data,size_t size)83 void DoCheckUri(const char* data, size_t size)
84 {
85 std::shared_ptr<Want> want = std::make_shared<Want>();
86 std::string values(data, size);
87 std::string emptyString;
88 want->CheckUri(emptyString);
89 want->CheckUri(values);
90 values.insert(0, Want::WANT_HEADER);
91 want->CheckUri(values);
92 values.append(Want::WANT_END);
93 want->CheckUri(values);
94 }
95
DoWriteAndReadUri(const char * data,size_t size)96 void DoWriteAndReadUri(const char* data, size_t size)
97 {
98 std::shared_ptr<Want> want = std::make_shared<Want>();
99 std::string values(data, size);
100 Parcel uriParcel;
101 want->WriteUri(uriParcel);
102 Uri uri(values);
103 want->SetUri(uri);
104 want->WriteUri(uriParcel);
105 want->ReadUri(uriParcel);
106 }
107
DoWriteAndReadEntities(const char * data,size_t size)108 void DoWriteAndReadEntities(const char* data, size_t size)
109 {
110 std::shared_ptr<Want> want = std::make_shared<Want>();
111 std::string values(data, size);
112 Parcel entitiesParcel;
113 want->WriteEntities(entitiesParcel);
114 want->AddEntity(values);
115 want->WriteEntities(entitiesParcel);
116 want->ReadEntities(entitiesParcel);
117 }
118
DoWriteAndReadElement(const char * data,size_t size)119 void DoWriteAndReadElement(const char* data, size_t size)
120 {
121 std::shared_ptr<Want> want = std::make_shared<Want>();
122 std::string values(data, size);
123 Parcel elementParcel;
124 want->WriteElement(elementParcel);
125 want->SetElementName(values, values);
126 want->WriteElement(elementParcel);
127 want->ReadElement(elementParcel);
128 }
129
DoWriteAndReadParameters(const char * data,size_t size)130 void DoWriteAndReadParameters(const char* data, size_t size)
131 {
132 std::shared_ptr<Want> want = std::make_shared<Want>();
133 Parcel parameters;
134 want->WriteParameters(parameters);
135 WantParams wantParams;
136 auto longValue = static_cast<long>(U32_AT_SIZE);
137 std::shared_ptr<Array> wantArray = std::make_shared<Array>(longValue, g_IID_IString);
138 std::string value(data, size);
139 sptr<IInterface> stringValue = String::Box(value);
140 for (size_t i = 0; i < longValue; i++) {
141 wantArray->Set(i, stringValue);
142 }
143 sptr<IInterface> wantArrayParam = Array::Parse(wantArray->ToString());
144 std::string wantArrayKey(1, Array::SIGNATURE);
145 wantParams.SetParam(wantArrayKey, wantArrayParam);
146 want->SetParams(wantParams);
147 want->WriteParameters(parameters);
148 want->ReadParameters(parameters);
149 }
150
151
DoSomethingInterestingWithMyAPI(const char * data,size_t size)152 bool DoSomethingInterestingWithMyAPI(const char* data, size_t size)
153 {
154 DoFromString(data, size);
155 DoCheckUri(data, size);
156 DoWriteAndReadUri(data, size);
157 DoWriteAndReadEntities(data, size);
158 DoWriteAndReadElement(data, size);
159 DoWriteAndReadParameters(data, size);
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 = reinterpret_cast<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