1 /*
2  * Copyright (c) 2023-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 <cerrno>
17 #include <fstream>
18 #include <sstream>
19 #include <unistd.h>
20 
21 #include "app_log_wrapper.h"
22 #include "bms_extension_profile.h"
23 
24 namespace OHOS {
25 namespace AppExecFwk {
26 namespace {
27 const int32_t BUFFER_SIZE = 256;
28 static const char* BMS_EXTENSION_PROFILE = "bms-extensions";
29 static const char* BMS_EXTENSION_PROFILE_BUNDLE_MGR = "bundle-mgr";
30 static const char* BUNDLE_MGR_KEY_EXTENSION_NAME = "extension-name";
31 static const char* BUNDLE_MGR_KEY_LIB_PATH = "libpath";
32 static const char* BUNDLE_MGR_KEY_LIB64_PATH = "lib64path";
33 }
34 
ParseBmsExtension(const std::string & jsonPath,BmsExtension & bmsExtension) const35 ErrCode BmsExtensionProfile::ParseBmsExtension(
36     const std::string &jsonPath, BmsExtension &bmsExtension) const
37 {
38     APP_LOGD("Parse BmsExtension from %{private}s", jsonPath.c_str());
39     nlohmann::json jsonBuf;
40     if (!ReadFileIntoJson(jsonPath, jsonBuf)) {
41         APP_LOGE("Parse bms-extension.json file failed, jsonPath: %{public}s", jsonPath.c_str());
42         return ERR_APPEXECFWK_PARSE_FILE_FAILED;
43     }
44     return TransformTo(jsonBuf, bmsExtension);
45 }
46 
ReadFileIntoJson(const std::string & filePath,nlohmann::json & jsonBuf) const47 bool BmsExtensionProfile::ReadFileIntoJson(const std::string &filePath, nlohmann::json &jsonBuf) const
48 {
49     if (access(filePath.c_str(), F_OK) != 0) {
50         APP_LOGE("access failed %{public}s errno:%{public}d", filePath.c_str(), errno);
51         return false;
52     }
53 
54     std::fstream in;
55     char errBuf[BUFFER_SIZE];
56     errBuf[0] = '\0';
57     in.open(filePath, std::ios_base::in);
58     if (!in.is_open()) {
59         strerror_r(errno, errBuf, sizeof(errBuf));
60         APP_LOGE("file open failed due to %{public}s, errno:%{public}d", errBuf, errno);
61         return false;
62     }
63 
64     in.seekg(0, std::ios::end);
65     int64_t size = in.tellg();
66     if (size <= 0) {
67         APP_LOGE("file is empty err %{public}d", errno);
68         in.close();
69         return false;
70     }
71 
72     in.seekg(0, std::ios::beg);
73     jsonBuf = nlohmann::json::parse(in, nullptr, false);
74     in.close();
75     if (jsonBuf.is_discarded()) {
76         APP_LOGE("bad profile file");
77         return false;
78     }
79 
80     return true;
81 }
82 
TransformTo(const nlohmann::json & jsonObject,BmsExtension & bmsExtension) const83 ErrCode BmsExtensionProfile::TransformTo(const nlohmann::json &jsonObject,
84     BmsExtension &bmsExtension) const
85 {
86     APP_LOGD("transform bms-extension.json stream to BmsExtension");
87     if (jsonObject.is_discarded()) {
88         APP_LOGE("profile format error");
89         return ERR_APPEXECFWK_PARSE_BAD_PROFILE;
90     }
91     if (jsonObject.find(BMS_EXTENSION_PROFILE) == jsonObject.end()) {
92         APP_LOGE("bms-extensions no exist");
93         return ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
94     }
95     nlohmann::json bmsExtensionJson = jsonObject.at(BMS_EXTENSION_PROFILE);
96     if (!bmsExtensionJson.is_object()) {
97         APP_LOGE("bms-extension.json file lacks of invalid bms-extensions property");
98         return ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
99     }
100     if (bmsExtensionJson.find(BMS_EXTENSION_PROFILE_BUNDLE_MGR) == bmsExtensionJson.end()) {
101         APP_LOGE("bundle-mgr no exist");
102         return ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
103     }
104     nlohmann::json bundleMgrJson = bmsExtensionJson.at(BMS_EXTENSION_PROFILE_BUNDLE_MGR);
105     if (!bundleMgrJson.is_object()) {
106         APP_LOGE("bms-extension.json file lacks of invalid bundle-mgr property");
107         return ERR_APPEXECFWK_PARSE_PROFILE_PROP_TYPE_ERROR;
108     }
109     const auto &jsonObjectEnd = bundleMgrJson.end();
110     int32_t parseResult = ERR_OK;
111     GetValueIfFindKey<std::string>(bundleMgrJson, jsonObjectEnd, BUNDLE_MGR_KEY_EXTENSION_NAME,
112         bmsExtension.bmsExtensionBundleMgr.extensionName, JsonType::STRING, true, parseResult, ArrayType::NOT_ARRAY);
113     GetValueIfFindKey<std::string>(bundleMgrJson, jsonObjectEnd, BUNDLE_MGR_KEY_LIB_PATH,
114         bmsExtension.bmsExtensionBundleMgr.libPath, JsonType::STRING, true, parseResult, ArrayType::NOT_ARRAY);
115     GetValueIfFindKey<std::string>(bundleMgrJson, jsonObjectEnd, BUNDLE_MGR_KEY_LIB64_PATH,
116         bmsExtension.bmsExtensionBundleMgr.lib64Path, JsonType::STRING, true, parseResult, ArrayType::NOT_ARRAY);
117     return parseResult;
118 }
119 }  // namespace AppExecFwk
120 }  // namespace OHOS
121 
122