1 /*
2  * Copyright (c) 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 
16 #include <cstring>
17 #include <map>
18 #include <securec.h>
19 #include <string>
20 #include <vector>
21 
22 #include "netstack_log.h"
23 #include "secure_char.h"
24 #include "websocket_client_innerapi.h"
25 
26 namespace OHOS {
27 namespace NetStack {
28 namespace WebSocketClient {
29 namespace {
30 OpenOptions openOptions;
31 std::map<std::string, std::string> headers = {
32     {"Content-Type", "application/json"},
33     {"Authorization", "Bearer your_token_here"},
34 };
35 const uint8_t *g_baseFuzzData = nullptr;
36 size_t g_baseFuzzSize = 0;
37 size_t g_baseFuzzPos = 0;
38 [[maybe_unused]] constexpr size_t STR_LEN = 255;
39 } // namespace
GetData()40 template <class T> T GetData()
41 {
42     T object{};
43     size_t objectSize = sizeof(object);
44     if (g_baseFuzzData == nullptr || g_baseFuzzSize <= g_baseFuzzPos || objectSize > g_baseFuzzSize - g_baseFuzzPos) {
45         return object;
46     }
47     errno_t ret = memcpy_s(&object, objectSize, g_baseFuzzData + g_baseFuzzPos, objectSize);
48     if (ret != EOK) {
49         return object;
50     }
51     g_baseFuzzPos += objectSize;
52     return object;
53 }
54 
SetGlobalFuzzData(const uint8_t * data,size_t size)55 void SetGlobalFuzzData(const uint8_t *data, size_t size)
56 {
57     g_baseFuzzData = data;
58     g_baseFuzzSize = size;
59     g_baseFuzzPos = 0;
60 }
61 
GetStringFromData(int strlen)62 std::string GetStringFromData(int strlen)
63 {
64     if (strlen < 1) {
65         return "";
66     }
67 
68     char cstr[strlen];
69     cstr[strlen - 1] = '\0';
70     for (int i = 0; i < strlen - 1; i++) {
71         cstr[i] = GetData<char>();
72     }
73     std::string str(cstr);
74     return str;
75 }
76 
OnMessage(WebSocketClient * client,const std::string & data,size_t length)77 static void OnMessage(WebSocketClient *client, const std::string &data, size_t length) {}
78 
OnOpen(WebSocketClient * client,OpenResult openResult)79 static void OnOpen(WebSocketClient *client, OpenResult openResult) {}
80 
OnError(WebSocketClient * client,ErrorResult error)81 static void OnError(WebSocketClient *client, ErrorResult error) {}
82 
OnClose(WebSocketClient * client,CloseResult closeResult)83 static void OnClose(WebSocketClient *client, CloseResult closeResult) {}
84 
SetRequestOptionsTest(const uint8_t * data,size_t size)85 void SetRequestOptionsTest(const uint8_t *data, size_t size)
86 {
87     if ((data == nullptr) || (size < 1)) {
88         return;
89     }
90     SetGlobalFuzzData(data, size);
91     std::string str = GetStringFromData(STR_LEN);
92     openOptions.headers["Content-Type"] = str;
93     openOptions.headers["Authorization"] = str;
94     WebSocketClient *client = new WebSocketClient();
95     client->Registcallback(OnOpen, OnMessage, OnError, OnClose);
96     client->Connect("www.baidu.com", openOptions);
97 }
98 
SetConnectUrlTest(const uint8_t * data,size_t size)99 void SetConnectUrlTest(const uint8_t *data, size_t size)
100 {
101     if (size < 1 || data == nullptr) {
102         return;
103     }
104     SetGlobalFuzzData(data, size);
105     std::string str = GetStringFromData(STR_LEN);
106     openOptions.headers["Authorization"] = "Bearer your_token_here";
107     openOptions.headers["Content-Type"] = "application/json";
108     WebSocketClient *client = new WebSocketClient();
109     client->Registcallback(OnOpen, OnMessage, OnError, OnClose);
110     client->Connect(str, openOptions);
111 }
112 
SetSendDataTest(const uint8_t * data,size_t size)113 void SetSendDataTest(const uint8_t *data, size_t size)
114 {
115     if ((data == nullptr) || (size < 1)) {
116         return;
117     }
118     openOptions.headers["Authorization"] = "Bearer your_token_here";
119     SetGlobalFuzzData(data, size);
120     std::string str = GetStringFromData(STR_LEN);
121     openOptions.headers["Content-Type"] = "application/json";
122     WebSocketClient *client = new WebSocketClient();
123     client->Registcallback(OnOpen, OnMessage, OnError, OnClose);
124     client->Connect("www.baidu.com", openOptions);
125     const char *data1 = str.c_str();
126     int32_t sendLength = std::strlen(data1);
127     client->Send(const_cast<char *>(data1), sendLength);
128 }
129 
SetSendDataLengthTest(const uint8_t * data,size_t size)130 void SetSendDataLengthTest(const uint8_t *data, size_t size)
131 {
132     if ((data == nullptr) || (size < 1)) {
133         return;
134     }
135     SetGlobalFuzzData(data, size);
136     openOptions.headers["Content-Type"] = "application/json";
137     openOptions.headers["Authorization"] = "Bearer your_token_here";
138     WebSocketClient *client = new WebSocketClient();
139     client->Registcallback(OnOpen, OnMessage, OnError, OnClose);
140     client->Connect("www.baidu.com", openOptions);
141     const char *data1 = "Hello,world!";
142     client->Send(const_cast<char *>(data1), size);
143 }
144 
SetCloseOptionTest(const uint8_t * data,size_t size)145 void SetCloseOptionTest(const uint8_t *data, size_t size)
146 {
147     if ((data == nullptr) || (size < 1)) {
148         return;
149     }
150     openOptions.headers["Content-Type"] = "application/json";
151     openOptions.headers["Authorization"] = "Bearer your_token_here";
152     SetGlobalFuzzData(data, size);
153     std::string str = GetStringFromData(STR_LEN);
154 
155     WebSocketClient *client = new WebSocketClient();
156     client->Registcallback(OnOpen, OnMessage, OnError, OnClose);
157     client->Connect("www.baidu.com", openOptions);
158     CloseOption CloseOptions;
159     CloseOptions.code = size;
160     CloseOptions.reason = str.c_str();
161     client->Close(CloseOptions);
162 }
163 
164 } // namespace WebSocketClient
165 } // namespace NetStack
166 } // namespace OHOS
167 
168 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)169 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
170 {
171     /* Run your code on data */
172     OHOS::NetStack::WebSocketClient::SetRequestOptionsTest(data, size);
173     OHOS::NetStack::WebSocketClient::SetConnectUrlTest(data, size);
174     OHOS::NetStack::WebSocketClient::SetSendDataTest(data, size);
175     OHOS::NetStack::WebSocketClient::SetSendDataLengthTest(data, size);
176     OHOS::NetStack::WebSocketClient::SetCloseOptionTest(data, size);
177     return 0;
178 }