/* * Copyright (c) 2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "updater_utils_fuzzer.h" #include #include #include #include #include #include #include "cJSON.h" #include "json_node.h" #include "log/log.h" #include "utils.h" using namespace std::literals; using namespace std; using namespace Updater; using namespace Utils; namespace { void CloseStdout(void) { int fd = open("/dev/null", O_RDWR | O_CLOEXEC); if (fd < 0) { return; } dup2(fd, 1); close(fd); } void TestTrim(const uint8_t* data, size_t size) { Utils::Trim(""); Utils::Trim(" "); Utils::Trim("aa "); Utils::Trim(std::string(reinterpret_cast(data), size)); } void TestConvertSha256Hex(void) { uint8_t a[1] = {0}; a[0] = 1; Utils::ConvertSha256Hex(a, 1); } void TestSplitString(void) { Utils::SplitString("aaa\nbbb", "\n"); } void TestMkdirRecursive(void) { Utils::MkdirRecursive("/data/xx?xx", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); } void TestString2Int(void) { Utils::String2Int("", 10); // 10 : size Utils::String2Int("0x01", 10); // 10 : size } void TestGetFilesFromDirectory(void) { std::vector files; Utils::SaveLogs(); Utils::CompressLogs("/data/updater/log/updater_log_test"); Utils::GetFilesFromDirectory("/data/updater/log", files, true); } void TestRemoveDir(void) { string path = ""; Utils::RemoveDir(path); path = "/data/updater/utils/nonExistDir"; Utils::RemoveDir(path); path = "/data/updater/rmDir"; int ret = mkdir(path.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); if (ret == 0) { ofstream tmpFile; string filePath = path + "/tmpFile"; tmpFile.open(filePath.c_str()); if (tmpFile.is_open()) { tmpFile.close(); Utils::RemoveDir(path); } } } void TestIsUpdaterMode(void) { Utils::IsUpdaterMode(); } void TestIsFileExist(void) { Utils::IsFileExist("/bin/test_updater"); Utils::IsFileExist("/bin/updater_binary"); } void TestIsDirExist(void) { Utils::IsDirExist("/bin/test_updater"); Utils::IsDirExist("/bin"); Utils::IsDirExist("/bin/"); } void TestCopyUpdaterLogs(void) { const std::string sLog = "/data/updater/main_data/updater.tab"; const std::string dLog = "/data/updater/main_data/ut_dLog.txt"; Utils::CopyUpdaterLogs(sLog, dLog); unlink(dLog.c_str()); } void TestGetDirSizeForFile(void) { Utils::GetDirSizeForFile("xxx"); Utils::GetDirSizeForFile("xxx/xxx"); Utils::GetDirSizeForFile("/data/updater/updater/etc/fstab.ut.updater"); } void TestJsonNodeValueKey(void) { { std::string str = R"({"key": "value1"})"; JsonNode node(str); node.Key(); node["key"].Key(); } { std::string str = R"({"key"})"; JsonNode node(str); node.Key(); } } void TestJsonNodeKey(void) { std::string str = R"({"key": "value1"})"; JsonNode node(str); node["key"]; } void TestJsonNodeValueTypeStr(void) { std::string str = R"({"key": "value1"})"; JsonNode node(str); node["key"].Type(); node["key"]; } void TestJsonNodeValueTypeInt(void) { std::string str = R"({"key": 1})"; JsonNode node(str); node["key"].Type(); node["key"]; } void TestJsonNodeValueTypeBool(void) { std::string str = R"({"key": true})"; JsonNode node(str); node["key"].Type(); node["key"]; } void TestJsonNodeValueTypeArray(void) { std::string str = R"({"key": [1, true, "value"]})"; JsonNode node(str); node["key"].Type(); node["key"][0]; node["key"][1]; node["key"][2]; // 2 : value index } void TestJsonNodeValueTypeObject(void) { std::string str = R"({"key": {"key" : "value"}}})"; JsonNode node(str); node["key"].Type(); node["key"]["key"]; } void TestJsonNodeValueTypeNull(void) { std::string str = R"({"key1": null})"; JsonNode node(str); node["key1"].Type(); } void TestJsonNodeValueTypeUnknow(void) { std::string str = R"({"key":})"; JsonNode node(str); node.Type(); } void TestJsonNodeValueTypeJsonNode(void) { std::string str = R"( { "A": "B", "C": { "D": "E", "F": { "G": { "H": "I", "J": 8879, "K": { "L": "M", "N": ["O", "P"] }, "L": true } } } })"; JsonNode node(str); const JsonNode &nodeC = node["C"]; const JsonNode &nodeG = nodeC["F"]["G"]; node.Type(); node["A"]; nodeC["D"]; nodeG["H"]; nodeG["J"]; nodeG["K"]["L"]; nodeG["K"]["N"][0]; nodeG["K"]["N"][1]; nodeG["L"]; } void TestJsonNodeKey1Type(void) { std::string str = R"({"key": "value1"})"; JsonNode node(str); node["key1"].Type(); } void TestJsonNodeValueTypeString(void) { { std::string str = R"({"key": "value1"})"; JsonNode node(str); node["key"].Type(); node["key1"].Type(); node["key"].Type(); } { std::string str = R"({"key": [1]})"; JsonNode node(str); node["key"].Type(); node["key"][0].Type(); node["key"][1].Type(); } } void TestJsonNodeTypeUnknow(void) { JsonNode node(Fs::path {R"(\invalid)"}); node.Type(); } void TestJsonNodeTypeUnknow1(void) { JsonNode node(Fs::path {"/data/noexist"}); node.Type(); } void TestJsonNodeFileType(void) { constexpr auto invalidContent = R"({ "key" : "value")"; constexpr auto invalidJsonPath = "/tmp/tmp.json"; { std::ofstream ofs(Fs::path {invalidJsonPath}); ofs << invalidContent; ofs.flush(); } JsonNode node(Fs::path {invalidJsonPath}); node.Type(); DeleteFile(invalidJsonPath); } void TestJsonNodeOperation(void) { std::string str = R"({"key":[1, true, "value"]})"; JsonNode node {str}; constexpr int intVal = 2; constexpr bool boolVal = false; const char *strVal = "newValue"; int idx = 0; node["key"][idx++] = intVal; node["key"][idx++] = boolVal; node["key"][idx++] = strVal; node["key"][--idx]; node["key"][--idx]; node["key"][--idx]; } void TestJsonNodeValueIntChange(void) { std::string str = R"({"key":1})"; JsonNode node {str}; constexpr int intVal = 2; node["key"] = intVal; node["key"]; } void TestJsonNodeValueBoolChange(void) { std::string str = R"({"key":true})"; JsonNode node {str}; constexpr bool boolVal = false; node["key"] = boolVal; node["key"]; } void TestJsonNodeValueStrChange(void) { std::string str = R"({"key":"value"})"; JsonNode node {str}; const char *strVal = "newValue"; node["key"] = strVal; node["key"]; } void TestJsonNodeValueArrayChange(void) { std::string str = R"({"key1":{ "key2":1, "key3":"value" }})"; JsonNode node {str}; constexpr int newValue = 2; node["key1"]["key2"] = newValue; node["key1"]["key3"] = "value2"; node["key1"]["key2"]; node["key1"]["key3"]; } void TestJsonNodeValueChange(void) { std::string str = R"({"key" : 1})"; JsonNode node {str}; node["key"] = false; node["key"]; node["key"] = "newValue"; node["key"]; } } namespace OHOS { void FuzzUtils(const uint8_t* data, size_t size) { CloseStdout(); TestTrim(data, size); TestConvertSha256Hex(); TestSplitString(); TestMkdirRecursive(); TestString2Int(); TestGetFilesFromDirectory(); TestRemoveDir(); TestIsUpdaterMode(); TestIsFileExist(); TestIsDirExist(); TestCopyUpdaterLogs(); TestGetDirSizeForFile(); TestJsonNodeValueKey(); TestJsonNodeKey(); TestJsonNodeValueTypeStr(); TestJsonNodeValueTypeInt(); TestJsonNodeValueTypeBool(); TestJsonNodeValueTypeArray(); TestJsonNodeValueTypeObject(); TestJsonNodeValueTypeNull(); TestJsonNodeValueTypeUnknow(); TestJsonNodeValueTypeJsonNode(); TestJsonNodeKey1Type(); TestJsonNodeValueTypeString(); TestJsonNodeTypeUnknow(); TestJsonNodeTypeUnknow1(); TestJsonNodeFileType(); TestJsonNodeOperation(); TestJsonNodeValueIntChange(); TestJsonNodeValueBoolChange(); TestJsonNodeValueStrChange(); TestJsonNodeValueArrayChange(); TestJsonNodeValueChange(); } } /* Fuzzer entry point */ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { /* Run your code on data */ OHOS::FuzzUtils(data, size); return 0; }