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 "updater_utils_fuzzer.h"
17 
18 #include <fcntl.h>
19 #include <fstream>
20 #include <iostream>
21 #include <sys/stat.h>
22 #include <unistd.h>
23 #include <vector>
24 #include "cJSON.h"
25 #include "json_node.h"
26 #include "log/log.h"
27 #include "utils.h"
28 
29 using namespace std::literals;
30 using namespace std;
31 using namespace Updater;
32 using namespace Utils;
33 
34 namespace {
CloseStdout(void)35 void CloseStdout(void)
36 {
37     int fd = open("/dev/null", O_RDWR | O_CLOEXEC);
38     if (fd < 0) {
39         return;
40     }
41     dup2(fd, 1);
42     close(fd);
43 }
44 
TestTrim(const uint8_t * data,size_t size)45 void TestTrim(const uint8_t* data, size_t size)
46 {
47     Utils::Trim("");
48     Utils::Trim("   ");
49     Utils::Trim("aa   ");
50     Utils::Trim(std::string(reinterpret_cast<const char*>(data), size));
51 }
52 
TestConvertSha256Hex(void)53 void TestConvertSha256Hex(void)
54 {
55     uint8_t a[1] = {0};
56     a[0] = 1;
57     Utils::ConvertSha256Hex(a, 1);
58 }
59 
TestSplitString(void)60 void TestSplitString(void)
61 {
62     Utils::SplitString("aaa\nbbb", "\n");
63 }
64 
TestMkdirRecursive(void)65 void TestMkdirRecursive(void)
66 {
67     Utils::MkdirRecursive("/data/xx?xx", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
68 }
69 
TestString2Int(void)70 void TestString2Int(void)
71 {
72     Utils::String2Int<int>("", 10); // 10 : size
73     Utils::String2Int<int>("0x01", 10); // 10 : size
74 }
75 
TestGetFilesFromDirectory(void)76 void TestGetFilesFromDirectory(void)
77 {
78     std::vector<std::string> files;
79     Utils::SaveLogs();
80     Utils::CompressLogs("/data/updater/log/updater_log_test");
81     Utils::GetFilesFromDirectory("/data/updater/log", files, true);
82 }
83 
TestRemoveDir(void)84 void TestRemoveDir(void)
85 {
86     string path = "";
87     Utils::RemoveDir(path);
88     path = "/data/updater/utils/nonExistDir";
89     Utils::RemoveDir(path);
90     path = "/data/updater/rmDir";
91     int ret = mkdir(path.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
92     if (ret == 0) {
93         ofstream tmpFile;
94         string filePath = path + "/tmpFile";
95         tmpFile.open(filePath.c_str());
96         if (tmpFile.is_open()) {
97             tmpFile.close();
98             Utils::RemoveDir(path);
99         }
100     }
101 }
102 
TestIsUpdaterMode(void)103 void TestIsUpdaterMode(void)
104 {
105     Utils::IsUpdaterMode();
106 }
107 
TestIsFileExist(void)108 void TestIsFileExist(void)
109 {
110     Utils::IsFileExist("/bin/test_updater");
111     Utils::IsFileExist("/bin/updater_binary");
112 }
113 
TestIsDirExist(void)114 void TestIsDirExist(void)
115 {
116     Utils::IsDirExist("/bin/test_updater");
117     Utils::IsDirExist("/bin");
118     Utils::IsDirExist("/bin/");
119 }
120 
TestCopyUpdaterLogs(void)121 void TestCopyUpdaterLogs(void)
122 {
123     const std::string sLog = "/data/updater/main_data/updater.tab";
124     const std::string dLog = "/data/updater/main_data/ut_dLog.txt";
125     Utils::CopyUpdaterLogs(sLog, dLog);
126     unlink(dLog.c_str());
127 }
128 
TestGetDirSizeForFile(void)129 void TestGetDirSizeForFile(void)
130 {
131     Utils::GetDirSizeForFile("xxx");
132     Utils::GetDirSizeForFile("xxx/xxx");
133     Utils::GetDirSizeForFile("/data/updater/updater/etc/fstab.ut.updater");
134 }
135 
TestJsonNodeValueKey(void)136 void TestJsonNodeValueKey(void)
137 {
138     {
139         std::string str = R"({"key": "value1"})";
140         JsonNode node(str);
141         node.Key();
142         node["key"].Key();
143     }
144     {
145         std::string str = R"({"key"})";
146         JsonNode node(str);
147         node.Key();
148     }
149 }
150 
TestJsonNodeKey(void)151 void TestJsonNodeKey(void)
152 {
153     std::string str = R"({"key": "value1"})";
154     JsonNode node(str);
155     node["key"];
156 }
157 
TestJsonNodeValueTypeStr(void)158 void TestJsonNodeValueTypeStr(void)
159 {
160     std::string str = R"({"key": "value1"})";
161     JsonNode node(str);
162     node["key"].Type();
163     node["key"];
164 }
165 
TestJsonNodeValueTypeInt(void)166 void TestJsonNodeValueTypeInt(void)
167 {
168     std::string str = R"({"key": 1})";
169     JsonNode node(str);
170     node["key"].Type();
171     node["key"];
172 }
173 
TestJsonNodeValueTypeBool(void)174 void TestJsonNodeValueTypeBool(void)
175 {
176     std::string str = R"({"key": true})";
177     JsonNode node(str);
178     node["key"].Type();
179     node["key"];
180 }
181 
TestJsonNodeValueTypeArray(void)182 void TestJsonNodeValueTypeArray(void)
183 {
184     std::string str = R"({"key": [1, true, "value"]})";
185     JsonNode node(str);
186     node["key"].Type();
187     node["key"][0];
188     node["key"][1];
189     node["key"][2]; // 2 : value index
190 }
191 
192 
TestJsonNodeValueTypeObject(void)193 void TestJsonNodeValueTypeObject(void)
194 {
195     std::string str = R"({"key": {"key" : "value"}}})";
196     JsonNode node(str);
197     node["key"].Type();
198     node["key"]["key"];
199 }
200 
TestJsonNodeValueTypeNull(void)201 void TestJsonNodeValueTypeNull(void)
202 {
203     std::string str = R"({"key1": null})";
204     JsonNode node(str);
205     node["key1"].Type();
206 }
207 
TestJsonNodeValueTypeUnknow(void)208 void TestJsonNodeValueTypeUnknow(void)
209 {
210     std::string str = R"({"key":})";
211     JsonNode node(str);
212     node.Type();
213 }
214 
TestJsonNodeValueTypeJsonNode(void)215 void TestJsonNodeValueTypeJsonNode(void)
216 {
217     std::string str = R"(
218     {
219         "A": "B",
220         "C": {
221             "D": "E",
222             "F": {
223                 "G": {
224                     "H": "I",
225                     "J": 8879,
226                     "K": {
227                         "L": "M",
228                         "N": ["O", "P"]
229                     },
230                     "L": true
231                 }
232             }
233         }
234     })";
235     JsonNode node(str);
236     const JsonNode &nodeC = node["C"];
237     const JsonNode &nodeG = nodeC["F"]["G"];
238     node.Type();
239     node["A"];
240     nodeC["D"];
241     nodeG["H"];
242     nodeG["J"];
243     nodeG["K"]["L"];
244     nodeG["K"]["N"][0];
245     nodeG["K"]["N"][1];
246     nodeG["L"];
247 }
248 
TestJsonNodeKey1Type(void)249 void TestJsonNodeKey1Type(void)
250 {
251     std::string str = R"({"key": "value1"})";
252     JsonNode node(str);
253     node["key1"].Type();
254 }
255 
TestJsonNodeValueTypeString(void)256 void TestJsonNodeValueTypeString(void)
257 {
258     {
259         std::string str = R"({"key": "value1"})";
260         JsonNode node(str);
261         node["key"].Type();
262         node["key1"].Type();
263         node["key"].Type();
264     }
265     {
266         std::string str = R"({"key": [1]})";
267         JsonNode node(str);
268         node["key"].Type();
269         node["key"][0].Type();
270         node["key"][1].Type();
271     }
272 }
273 
TestJsonNodeTypeUnknow(void)274 void TestJsonNodeTypeUnknow(void)
275 {
276     JsonNode node(Fs::path {R"(\invalid)"});
277     node.Type();
278 }
279 
TestJsonNodeTypeUnknow1(void)280 void TestJsonNodeTypeUnknow1(void)
281 {
282     JsonNode node(Fs::path {"/data/noexist"});
283     node.Type();
284 }
285 
TestJsonNodeFileType(void)286 void TestJsonNodeFileType(void)
287 {
288     constexpr auto invalidContent = R"({ "key" : "value")";
289     constexpr auto invalidJsonPath = "/tmp/tmp.json";
290     {
291         std::ofstream ofs(Fs::path {invalidJsonPath});
292         ofs << invalidContent;
293         ofs.flush();
294     }
295     JsonNode node(Fs::path {invalidJsonPath});
296     node.Type();
297     DeleteFile(invalidJsonPath);
298 }
299 
TestJsonNodeOperation(void)300 void TestJsonNodeOperation(void)
301 {
302     std::string str = R"({"key":[1, true, "value"]})";
303     JsonNode node {str};
304     constexpr int intVal = 2;
305     constexpr bool boolVal = false;
306     const char *strVal = "newValue";
307     int idx = 0;
308     node["key"][idx++] = intVal;
309     node["key"][idx++] = boolVal;
310     node["key"][idx++] = strVal;
311     node["key"][--idx];
312     node["key"][--idx];
313     node["key"][--idx];
314 }
315 
TestJsonNodeValueIntChange(void)316 void TestJsonNodeValueIntChange(void)
317 {
318     std::string str = R"({"key":1})";
319     JsonNode node {str};
320     constexpr int intVal = 2;
321     node["key"] = intVal;
322     node["key"];
323 }
324 
TestJsonNodeValueBoolChange(void)325 void TestJsonNodeValueBoolChange(void)
326 {
327     std::string str = R"({"key":true})";
328     JsonNode node {str};
329     constexpr bool boolVal = false;
330     node["key"] = boolVal;
331     node["key"];
332 }
333 
TestJsonNodeValueStrChange(void)334 void TestJsonNodeValueStrChange(void)
335 {
336     std::string str = R"({"key":"value"})";
337     JsonNode node {str};
338     const char *strVal = "newValue";
339     node["key"] = strVal;
340     node["key"];
341 }
342 
TestJsonNodeValueArrayChange(void)343 void TestJsonNodeValueArrayChange(void)
344 {
345     std::string str = R"({"key1":{
346         "key2":1,
347         "key3":"value"
348     }})";
349     JsonNode node {str};
350     constexpr int newValue = 2;
351     node["key1"]["key2"] = newValue;
352     node["key1"]["key3"] = "value2";
353     node["key1"]["key2"];
354     node["key1"]["key3"];
355 }
356 
TestJsonNodeValueChange(void)357 void TestJsonNodeValueChange(void)
358 {
359     std::string str = R"({"key" : 1})";
360     JsonNode node {str};
361     node["key"] = false;
362     node["key"];
363     node["key"] = "newValue";
364     node["key"];
365 }
366 }
367 
368 namespace OHOS {
FuzzUtils(const uint8_t * data,size_t size)369     void FuzzUtils(const uint8_t* data, size_t size)
370     {
371         CloseStdout();
372         TestTrim(data, size);
373         TestConvertSha256Hex();
374         TestSplitString();
375         TestMkdirRecursive();
376         TestString2Int();
377         TestGetFilesFromDirectory();
378         TestRemoveDir();
379         TestIsUpdaterMode();
380         TestIsFileExist();
381         TestIsDirExist();
382         TestCopyUpdaterLogs();
383         TestGetDirSizeForFile();
384         TestJsonNodeValueKey();
385         TestJsonNodeKey();
386         TestJsonNodeValueTypeStr();
387         TestJsonNodeValueTypeInt();
388         TestJsonNodeValueTypeBool();
389         TestJsonNodeValueTypeArray();
390         TestJsonNodeValueTypeObject();
391         TestJsonNodeValueTypeNull();
392         TestJsonNodeValueTypeUnknow();
393         TestJsonNodeValueTypeJsonNode();
394         TestJsonNodeKey1Type();
395         TestJsonNodeValueTypeString();
396         TestJsonNodeTypeUnknow();
397         TestJsonNodeTypeUnknow1();
398         TestJsonNodeFileType();
399         TestJsonNodeOperation();
400         TestJsonNodeValueIntChange();
401         TestJsonNodeValueBoolChange();
402         TestJsonNodeValueStrChange();
403         TestJsonNodeValueArrayChange();
404         TestJsonNodeValueChange();
405     }
406 }
407 
408 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)409 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
410 {
411     /* Run your code on data */
412     OHOS::FuzzUtils(data, size);
413     return 0;
414 }
415