• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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 "bundle_parser.h"
17 
18 #include <fstream>
19 #include <sstream>
20 #include <unistd.h>
21 
22 #include "app_log_wrapper.h"
23 #include "app_privilege_capability.h"
24 #include "bundle_constants.h"
25 #include "bundle_extractor.h"
26 #include "bundle_profile.h"
27 #include "default_permission_profile.h"
28 #include "module_profile.h"
29 #include "pre_bundle_profile.h"
30 #include "rpcid_decode/syscap_tool.h"
31 #include "securec.h"
32 
33 namespace OHOS {
34 namespace AppExecFwk {
35 namespace {
36 const std::string INSTALL_ABILITY_CONFIGS = "install_ability_configs";
37 
ParseStr(const char * buf,const int itemLen,int totalLen,std::vector<std::string> & sysCaps)38 bool ParseStr(const char *buf, const int itemLen, int totalLen, std::vector<std::string> &sysCaps)
39 {
40     APP_LOGD("Parse rpcid output start, itemLen:%{public}d  totalLen:%{public}d.", itemLen, totalLen);
41     if (buf == nullptr || itemLen <= 0 || totalLen <= 0) {
42         APP_LOGE("param invalid.");
43         return false;
44     }
45 
46     int index = 0;
47     while (index + itemLen <= totalLen) {
48         char item[itemLen];
49         if (strncpy_s(item, sizeof(item), buf + index, itemLen) != 0) {
50             APP_LOGE("Parse rpcid failed due to strncpy_s error.");
51             return false;
52         }
53 
54         sysCaps.emplace_back((std::string)item, 0, itemLen);
55         index += itemLen;
56     }
57 
58     return true;
59 }
60 } // namespace
61 
ReadFileIntoJson(const std::string & filePath,nlohmann::json & jsonBuf)62 bool BundleParser::ReadFileIntoJson(const std::string &filePath, nlohmann::json &jsonBuf)
63 {
64     if (access(filePath.c_str(), F_OK) != 0) {
65         APP_LOGE("can not access the file: %{public}s", filePath.c_str());
66         return false;
67     }
68 
69     std::fstream in;
70     char errBuf[256];
71     errBuf[0] = '\0';
72     in.open(filePath, std::ios_base::in);
73     if (!in.is_open()) {
74         strerror_r(errno, errBuf, sizeof(errBuf));
75         APP_LOGE("the file cannot be open due to  %{public}s", errBuf);
76         return false;
77     }
78 
79     in.seekg(0, std::ios::end);
80     int64_t size = in.tellg();
81     if (size <= 0) {
82         APP_LOGE("the file is an empty file");
83         in.close();
84         return false;
85     }
86 
87     in.seekg(0, std::ios::beg);
88     jsonBuf = nlohmann::json::parse(in, nullptr, false);
89     in.close();
90     if (jsonBuf.is_discarded()) {
91         APP_LOGE("bad profile file");
92         return false;
93     }
94 
95     return true;
96 }
97 
Parse(const std::string & pathName,InnerBundleInfo & innerBundleInfo) const98 ErrCode BundleParser::Parse(
99     const std::string &pathName,
100     InnerBundleInfo &innerBundleInfo) const
101 {
102     APP_LOGI("parse from %{private}s", pathName.c_str());
103     BundleExtractor bundleExtractor(pathName);
104     if (!bundleExtractor.Init()) {
105         APP_LOGE("bundle extractor init failed");
106         return ERR_APPEXECFWK_PARSE_UNEXPECTED;
107     }
108 
109     // to extract config.json
110     std::ostringstream outStream;
111     if (!bundleExtractor.ExtractProfile(outStream)) {
112         APP_LOGE("extract profile file failed");
113         return ERR_APPEXECFWK_PARSE_NO_PROFILE;
114     }
115 
116     if (bundleExtractor.IsNewVersion()) {
117         APP_LOGD("module.json transform to InnerBundleInfo");
118         innerBundleInfo.SetIsNewVersion(true);
119         ModuleProfile moduleProfile;
120         return moduleProfile.TransformTo(
121             outStream, bundleExtractor, innerBundleInfo);
122     }
123     APP_LOGD("config.json transform to InnerBundleInfo");
124     innerBundleInfo.SetIsNewVersion(false);
125     BundleProfile bundleProfile;
126     ErrCode ret = bundleProfile.TransformTo(
127         outStream, bundleExtractor, innerBundleInfo);
128     if (ret != ERR_OK) {
129         APP_LOGE("transform stream to innerBundleInfo failed %{public}d", ret);
130         return ret;
131     }
132     auto& abilityInfos = innerBundleInfo.FetchAbilityInfos();
133     for (auto& info : abilityInfos) {
134         info.second.isStageBasedModel = bundleExtractor.IsStageBasedModel(info.second.name);
135         auto iter = innerBundleInfo.FetchInnerModuleInfos().find(info.second.package);
136         if (iter != innerBundleInfo.FetchInnerModuleInfos().end()) {
137             iter->second.isStageBasedModel = info.second.isStageBasedModel;
138         }
139     }
140 
141     return ERR_OK;
142 }
143 
ParsePackInfo(const std::string & pathName,BundlePackInfo & bundlePackInfo) const144 ErrCode BundleParser::ParsePackInfo(const std::string &pathName, BundlePackInfo &bundlePackInfo) const
145 {
146     APP_LOGI("parse from %{private}s", pathName.c_str());
147     BundleExtractor bundleExtractor(pathName);
148     if (!bundleExtractor.Init()) {
149         APP_LOGE("bundle extractor init failed");
150         return ERR_APPEXECFWK_PARSE_UNEXPECTED;
151     }
152 
153     // to extract pack.info
154     if (!bundleExtractor.HasEntry(Constants::BUNDLE_PACKFILE_NAME)) {
155         APP_LOGW("cannot find pack.info in the hap file");
156         return ERR_OK;
157     }
158     std::ostringstream outStreamForPackInfo;
159     if (!bundleExtractor.ExtractPackFile(outStreamForPackInfo)) {
160         APP_LOGE("extract profile file failed");
161         return ERR_APPEXECFWK_PARSE_NO_PROFILE;
162     }
163     BundleProfile bundleProfile;
164     ErrCode ret = bundleProfile.TransformTo(outStreamForPackInfo, bundlePackInfo);
165     if (ret != ERR_OK) {
166         APP_LOGE("transform stream to bundlePackinfo failed %{public}d", ret);
167         return ret;
168     }
169     return ERR_OK;
170 }
171 
ParseSysCap(const std::string & pathName,std::vector<std::string> & sysCaps) const172 ErrCode BundleParser::ParseSysCap(const std::string &pathName, std::vector<std::string> &sysCaps) const
173 {
174     APP_LOGD("Parse sysCaps from %{private}s", pathName.c_str());
175     BundleExtractor bundleExtractor(pathName);
176     if (!bundleExtractor.Init()) {
177         APP_LOGE("Bundle extractor init failed");
178         return ERR_APPEXECFWK_PARSE_UNEXPECTED;
179     }
180 
181     if (!bundleExtractor.HasEntry(Constants::SYSCAP_NAME)) {
182         APP_LOGD("Rpcid.sc is not exist, and do not need verification sysCaps.");
183         return ERR_OK;
184     }
185 
186     std::stringstream rpcidStream;
187     if (!bundleExtractor.ExtractByName(Constants::SYSCAP_NAME, rpcidStream)) {
188         APP_LOGE("Extract rpcid file failed");
189         return ERR_APPEXECFWK_PARSE_RPCID_FAILED;
190     }
191 
192     int32_t rpcidLen = rpcidStream.tellp();
193     if (rpcidLen < 0) {
194         return ERR_APPEXECFWK_PARSE_UNEXPECTED;
195     }
196     char rpcidBuf[rpcidLen];
197     rpcidStream.read(rpcidBuf, rpcidLen);
198     uint32_t outLen;
199     char *outBuffer;
200     int result = RPCIDStreamDecodeToBuffer(rpcidBuf, rpcidLen, &outBuffer, &outLen);
201     if (result != 0) {
202         APP_LOGE("Decode syscaps failed");
203         return ERR_APPEXECFWK_PARSE_RPCID_FAILED;
204     }
205 
206     if (!ParseStr(outBuffer, SINGLE_SYSCAP_LENGTH, outLen, sysCaps)) {
207         APP_LOGE("Parse syscaps str failed");
208         free(outBuffer);
209         return ERR_APPEXECFWK_PARSE_RPCID_FAILED;
210     }
211 
212     APP_LOGD("Parse sysCaps str success");
213     free(outBuffer);
214     return ERR_OK;
215 }
216 
ParsePreInstallConfig(const std::string & configFile,std::set<PreScanInfo> & scanInfos) const217 ErrCode BundleParser::ParsePreInstallConfig(
218     const std::string &configFile, std::set<PreScanInfo> &scanInfos) const
219 {
220     APP_LOGD("Parse preInstallConfig from %{public}s", configFile.c_str());
221     nlohmann::json jsonBuf;
222     if (!ReadFileIntoJson(configFile, jsonBuf)) {
223         APP_LOGE("Parse preInstallConfig file failed");
224         return ERR_APPEXECFWK_PARSE_FILE_FAILED;
225     }
226 
227     PreBundleProfile preBundleProfile;
228     return preBundleProfile.TransformTo(jsonBuf, scanInfos);
229 }
230 
ParsePreUnInstallConfig(const std::string & configFile,std::set<std::string> & uninstallList) const231 ErrCode BundleParser::ParsePreUnInstallConfig(
232     const std::string &configFile,
233     std::set<std::string> &uninstallList) const
234 {
235     APP_LOGD("Parse PreUnInstallConfig from %{public}s", configFile.c_str());
236     nlohmann::json jsonBuf;
237     if (!ReadFileIntoJson(configFile, jsonBuf)) {
238         APP_LOGE("Parse preUnInstallConfig file failed");
239         return ERR_APPEXECFWK_PARSE_FILE_FAILED;
240     }
241 
242     PreBundleProfile preBundleProfile;
243     return preBundleProfile.TransformTo(jsonBuf, uninstallList);
244 }
245 
ParsePreInstallAbilityConfig(const std::string & configFile,std::set<PreBundleConfigInfo> & preBundleConfigInfos) const246 ErrCode BundleParser::ParsePreInstallAbilityConfig(
247     const std::string &configFile, std::set<PreBundleConfigInfo> &preBundleConfigInfos) const
248 {
249     APP_LOGD("Parse PreInstallAbilityConfig from %{public}s", configFile.c_str());
250     nlohmann::json jsonBuf;
251     if (!ReadFileIntoJson(configFile, jsonBuf)) {
252         APP_LOGE("Parse preInstallAbilityConfig file failed");
253         return ERR_APPEXECFWK_PARSE_FILE_FAILED;
254     }
255 
256     PreBundleProfile preBundleProfile;
257     return preBundleProfile.TransformTo(jsonBuf, preBundleConfigInfos);
258 }
259 
ParseDefaultPermission(const std::string & permissionFile,std::set<DefaultPermission> & defaultPermissions) const260 ErrCode BundleParser::ParseDefaultPermission(
261     const std::string &permissionFile, std::set<DefaultPermission> &defaultPermissions) const
262 {
263     APP_LOGD("Parse DefaultPermission from %{private}s", permissionFile.c_str());
264     nlohmann::json jsonBuf;
265     if (!ReadFileIntoJson(permissionFile, jsonBuf)) {
266         APP_LOGE("Parse default-permissions file failed");
267         return ERR_APPEXECFWK_PARSE_FILE_FAILED;
268     }
269 
270     DefaultPermissionProfile profile;
271     return profile.TransformTo(jsonBuf, defaultPermissions);
272 }
273 }  // namespace AppExecFwk
274 }  // namespace OHOS
275