1 /*
2 * Copyright (c) 2020-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 "gt_bundle_parser.h"
17
18 #include <cstdio>
19 #include <cstdlib>
20
21 #include "ability_info_utils.h"
22 #include "adapter.h"
23 #include "appexecfwk_errors.h"
24 #include "bundle_info_utils.h"
25 #include "bundle_util.h"
26 #include "bundlems_log.h"
27 #include "fcntl.h"
28 #include "global.h"
29 #include "gt_bundle_extractor.h"
30 #include "module_info_utils.h"
31 #include "parameter.h"
32 #include "pms.h"
33 #include "securec.h"
34 #include "sys/stat.h"
35 #include "unistd.h"
36 #include "utils.h"
37
38 namespace OHOS {
39 const int32_t BASE_API_VERSION = 3;
40 const int32_t API_VERSION_MASK = 1000;
41 const char *DEVICE_API_VERSION_KEY = "const.product.os.dist.apiversion";
42 const int32_t DEVICE_API_VERSION_LEN = 16;
43 const int32_t DEVICE_API_VERSION_MINI_LEN = 5;
44 const int32_t STRTOL_DECIMALISM_FLAG = 10;
45 const char STRING_END_FLAG = '\0';
46
ParseValue(const cJSON * object,const char * key,int32_t defaultValue)47 int32_t GtBundleParser::ParseValue(const cJSON *object, const char *key, int32_t defaultValue)
48 {
49 if (object == nullptr) {
50 return defaultValue;
51 }
52
53 cJSON *son = nullptr;
54 son = cJSON_GetObjectItem(object, key);
55 if (!cJSON_IsNumber(son)) {
56 return defaultValue;
57 }
58 return son->valueint;
59 }
60
ParseValue(const cJSON * object,const char * key)61 char *GtBundleParser::ParseValue(const cJSON *object, const char *key)
62 {
63 if (object == nullptr) {
64 return nullptr;
65 }
66
67 cJSON *son = nullptr;
68 son = cJSON_GetObjectItem(object, key);
69 if (!cJSON_IsString(son)) {
70 return nullptr;
71 }
72 return son->valuestring;
73 }
74
ParseValue(const cJSON * object,const char * key,cJSON * defaultValue)75 cJSON *GtBundleParser::ParseValue(const cJSON *object, const char *key, cJSON *defaultValue)
76 {
77 if (object == nullptr) {
78 return defaultValue;
79 }
80
81 cJSON *son = nullptr;
82 son = cJSON_GetObjectItem(object, key);
83 if (son == nullptr) {
84 return defaultValue;
85 }
86
87 if (cJSON_IsArray(son) || cJSON_IsObject(son)) {
88 return son;
89 }
90 return defaultValue;
91 }
92
ParseBundleAttr(const char * path,char ** bundleName,int32_t & versionCode)93 bool GtBundleParser::ParseBundleAttr(const char *path, char **bundleName, int32_t &versionCode)
94 {
95 if (!BundleUtil::CheckRealPath(path)) {
96 return false;
97 }
98
99 uint32_t totalFileSize = BundleUtil::GetFileSize(path);
100 int32_t fp = open(path, O_RDONLY, S_IREAD);
101 if (fp < 0) {
102 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] open file failed!");
103 return false;
104 }
105
106 char *profileStr = GtBundleExtractor::ExtractHapProfile(fp, totalFileSize);
107 if (profileStr == nullptr) {
108 close(fp);
109 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] ExtractHapProfile failed when excute parse bundle!");
110 return false;
111 }
112 close(fp);
113
114 cJSON *root = cJSON_Parse(profileStr);
115 if (root == nullptr) {
116 AdapterFree(profileStr);
117 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] cJSON_Parse failed when excute parse bundle!");
118 return false;
119 }
120 AdapterFree(profileStr);
121
122 cJSON *appObject = cJSON_GetObjectItem(root, PROFILE_KEY_APP);
123 if (appObject == nullptr) {
124 cJSON_Delete(root);
125 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] cJSON_GetObjectItem failed when excute parse bundle!");
126 return false;
127 }
128
129 *bundleName = Utils::Strdup(ParseValue(appObject, PROFILE_KEY_BUNDLENAME));
130 if (*bundleName == nullptr) {
131 cJSON_Delete(root);
132 return false;
133 }
134
135 cJSON *object = ParseValue(appObject, PROFILE_KEY_VERSION, nullptr);
136 if (object == nullptr) {
137 cJSON_Delete(root);
138 return false;
139 }
140
141 versionCode = ParseValue(object, PROFILE_KEY_VERSION_CODE, -1);
142 if (versionCode == -1) {
143 cJSON_Delete(root);
144 return false;
145 }
146 cJSON_Delete(root);
147 return true;
148 }
149
ParseHapProfile(const char * path,BundleRes * bundleRes)150 BundleInfo *GtBundleParser::ParseHapProfile(const char *path, BundleRes *bundleRes)
151 {
152 if (!BundleUtil::CheckRealPath(path) || bundleRes == nullptr) {
153 return nullptr;
154 }
155
156 char profilePath[PATH_LENGTH] = { 0 };
157 if (sprintf_s(profilePath, PATH_LENGTH, "%s/%s", path, PROFILE_NAME) < 0) {
158 return nullptr;
159 }
160
161 cJSON *root = BundleUtil::GetJsonStream(profilePath);
162 if (root == nullptr) {
163 return nullptr;
164 }
165
166 cJSON *appObject = cJSON_GetObjectItem(root, PROFILE_KEY_APP);
167 cJSON *configObject = cJSON_GetObjectItem(root, PROFILE_KEY_DEVICECONFIG);
168 cJSON *moduleObject = cJSON_GetObjectItem(root, PROFILE_KEY_MODULE);
169 if (appObject == nullptr || moduleObject == nullptr) {
170 cJSON_Delete(root);
171 return nullptr;
172 }
173
174 BundleProfile bundleProfile;
175 if (memset_s(&bundleProfile, sizeof(BundleProfile), 0, sizeof(BundleProfile)) != EOK) {
176 cJSON_Delete(root);
177 return nullptr;
178 }
179
180 if (ParseJsonInfo(appObject, configObject, moduleObject, bundleProfile, *bundleRes) != ERR_OK) {
181 cJSON_Delete(root);
182 FREE_BUNDLE_PROFILE(bundleProfile);
183 return nullptr;
184 }
185
186 BundleInfo *bundleInfo = CreateBundleInfo(path, bundleProfile, *bundleRes);
187 FREE_BUNDLE_PROFILE(bundleProfile);
188 cJSON_Delete(root);
189 return bundleInfo;
190 }
191
ParseJsonInfo(const cJSON * appObject,const cJSON * configObject,const cJSON * moduleObject,BundleProfile & bundleProfile,BundleRes & bundleRes)192 uint8_t GtBundleParser::ParseJsonInfo(const cJSON *appObject, const cJSON *configObject, const cJSON *moduleObject,
193 BundleProfile &bundleProfile, BundleRes &bundleRes)
194 {
195 // parse app config
196 bundleProfile.bundleName = ParseValue(appObject, PROFILE_KEY_BUNDLENAME);
197 CHECK_NULL(bundleProfile.bundleName, ERR_APPEXECFWK_INSTALL_FAILED_PARSE_BUNDLENAME_ERROR);
198 if (!((strlen(bundleProfile.bundleName) >= MIN_BUNDLE_NAME_LEN) &&
199 (strlen(bundleProfile.bundleName) <= MAX_BUNDLE_NAME_LEN))) {
200 return ERR_APPEXECFWK_INSTALL_FAILED_PARSE_INVALID_BUNDLENAME_LENGTH;
201 }
202
203 if (cJSON_HasObjectItem(appObject, PROFILE_KEY_VENDOR)) {
204 bundleProfile.vendor = ParseValue(appObject, PROFILE_KEY_VENDOR);
205 CHECK_NULL(bundleProfile.vendor, ERR_APPEXECFWK_INSTALL_FAILED_PARSE_VENDOR_ERROR);
206 }
207
208 cJSON *object = ParseValue(appObject, PROFILE_KEY_VERSION, nullptr);
209 bundleProfile.profileVersion.versionName = ParseValue(object, PROFILE_KEY_VERSION_NAME);
210 CHECK_NULL(bundleProfile.profileVersion.versionName, ERR_APPEXECFWK_INSTALL_FAILED_PARSE_VERSIONNAME_ERROR);
211 CHECK_LENGTH(strlen(bundleProfile.profileVersion.versionName), MAX_VERSION_NAME_LEN,
212 ERR_APPEXECFWK_INSTALL_FAILED_EXCEED_MAX_VERSIONNAME_LENGTH_ERROR);
213
214 bundleProfile.profileVersion.versionCode = ParseValue(object, PROFILE_KEY_VERSION_CODE, -1);
215 if (bundleProfile.profileVersion.versionCode == -1) {
216 return ERR_APPEXECFWK_INSTALL_FAILED_PARSE_VERSIONCODE_ERROR;
217 }
218 // check apiVersion
219 uint8_t checkRet = CheckApiVersion(appObject, bundleProfile);
220 CHECK_IS_TRUE((checkRet == ERR_OK), ERR_APPEXECFWK_INSTALL_FAILED_PARSE_API_VERSION_ERROR);
221
222 uint8_t errorCode = ParseModuleInfo(moduleObject, bundleProfile, bundleRes);
223 return errorCode;
224 }
225
CheckApiVersion(const cJSON * appObject,BundleProfile & bundleProfile)226 uint8_t GtBundleParser::CheckApiVersion(const cJSON *appObject, BundleProfile &bundleProfile)
227 {
228 if (!cJSON_HasObjectItem(appObject, PROFILE_KEY_APIVERSION)) {
229 // parse deviceConfig
230 bundleProfile.profileApiVersion.minApiVersion = BASE_API_VERSION;
231 bundleProfile.profileApiVersion.maxApiVersion = BASE_API_VERSION;
232 return ERR_OK;
233 }
234 cJSON *object = ParseValue(appObject, PROFILE_KEY_APIVERSION, nullptr);
235 CHECK_NULL(object, ERR_APPEXECFWK_INSTALL_FAILED_PARSE_API_VERSION_ERROR);
236 if (!cJSON_HasObjectItem(object, PROFILE_KEY_APIVERSION_COMPATIBLE) ||
237 !cJSON_HasObjectItem(object, PROFILE_KEY_APIVERSION_TARGET)) {
238 return ERR_APPEXECFWK_INSTALL_FAILED_PARSE_API_VERSION_ERROR;
239 }
240 bundleProfile.profileApiVersion.minApiVersion = ParseValue(object, PROFILE_KEY_APIVERSION_COMPATIBLE, -1);
241 bundleProfile.profileApiVersion.maxApiVersion = ParseValue(object, PROFILE_KEY_APIVERSION_TARGET, -1);
242 CHECK_IS_TRUE(
243 (bundleProfile.profileApiVersion.maxApiVersion >= bundleProfile.profileApiVersion.minApiVersion),
244 ERR_APPEXECFWK_INSTALL_FAILED_PARSE_API_VERSION_ERROR);
245 // API 10
246 if (bundleProfile.profileApiVersion.minApiVersion >= API_VERSION_MASK) {
247 uint8_t checkRet = CheckApi10Version(bundleProfile.profileApiVersion.minApiVersion);
248 CHECK_IS_TRUE((checkRet == ERR_OK), ERR_APPEXECFWK_INSTALL_FAILED_PARSE_API_VERSION_ERROR);
249 }
250 return ERR_OK;
251 }
252
CheckApi10Version(int32_t compatibleApiVersion)253 uint8_t GtBundleParser::CheckApi10Version(int32_t compatibleApiVersion)
254 {
255 int32_t apiLevel = GetSdkApiVersion();
256 char value[DEVICE_API_VERSION_LEN] = {0};
257 int32_t ret = GetParameter(DEVICE_API_VERSION_KEY, "", value, DEVICE_API_VERSION_LEN);
258 CHECK_IS_TRUE((ret >= 0), ERR_APPEXECFWK_INSTALL_FAILED_PARSE_API_VERSION_ERROR);
259 CHECK_IS_TRUE((strlen(value) >= DEVICE_API_VERSION_MINI_LEN),
260 ERR_APPEXECFWK_INSTALL_FAILED_PARSE_API_VERSION_ERROR);
261 char* endptr;
262 long num = strtol(value, &endptr, STRTOL_DECIMALISM_FLAG);
263 CHECK_IS_TRUE((*endptr == STRING_END_FLAG), ERR_APPEXECFWK_INSTALL_FAILED_PARSE_API_VERSION_ERROR);
264 int32_t apiVersion = static_cast<int32_t>(num);
265 int32_t deviceVersion = apiVersion * API_VERSION_MASK + apiLevel;
266 CHECK_IS_TRUE((deviceVersion >= compatibleApiVersion), ERR_APPEXECFWK_INSTALL_FAILED_PARSE_API_VERSION_ERROR);
267 return ERR_OK;
268 }
269
ParseModuleInfo(const cJSON * moduleObject,BundleProfile & bundleProfile,BundleRes & bundleRes)270 uint8_t GtBundleParser::ParseModuleInfo(const cJSON *moduleObject, BundleProfile &bundleProfile, BundleRes &bundleRes)
271 {
272 // parse deviceType
273 cJSON *object = ParseValue(moduleObject, PROFILE_KEY_MODULE_DEVICETYPE, nullptr);
274 if (!CheckDeviceTypeIsValid(object)) {
275 return ERR_APPEXECFWK_INSTALL_FAILED_PARSE_DEVICETYPE_ERROR;
276 }
277 // parse distro
278 object = ParseValue(moduleObject, PROFILE_KEY_MODULE_DISTRO, nullptr);
279 CHECK_NULL(object, ERR_APPEXECFWK_INSTALL_FAILED_PARSE_DISTRO_ERROR);
280 cJSON *deliveryObject = cJSON_GetObjectItem(object, PROFILE_KEY_MODULE_DISTRO_DELIVERY);
281 CHECK_NULL(deliveryObject, ERR_APPEXECFWK_INSTALL_FAILED_PARSE_DISTRO_DELIVERY_ERROR);
282 if (!cJSON_IsBool(deliveryObject)) {
283 return ERR_APPEXECFWK_INSTALL_FAILED_PARSE_DISTRO_DELIVERY_ERROR;
284 }
285
286 bundleProfile.moduleInfo.moduleName = ParseValue(object, PROFILE_KEY_MODULE_DISTRO_MODULENAME);
287 CHECK_NULL(bundleProfile.moduleInfo.moduleName, ERR_APPEXECFWK_INSTALL_FAILED_PARSE_DISTRO_MODULENAME_ERROR);
288 if (strstr(bundleProfile.moduleInfo.moduleName, "../") != nullptr) {
289 return ERR_APPEXECFWK_INSTALL_FAILED_PARSE_INVALID_MODULENAME;
290 }
291 // parse metaData
292 uint8_t errorCode = ParseModuleMetaData(moduleObject, bundleProfile);
293 if (errorCode != ERR_OK) {
294 return errorCode;
295 }
296
297 char *moduleType = ParseValue(object, PROFILE_KEY_MODULE_DISTRO_MODULETYPE);
298 CHECK_NULL(moduleType, ERR_APPEXECFWK_INSTALL_FAILED_PARSE_DISTRO_MODULETYPE_ERROR);
299 bool result = ((strcmp(moduleType, MODULE_ENTRY) == 0) || (strcmp(moduleType, MODULE_FEATURE) == 0));
300 if (!result) {
301 return ERR_APPEXECFWK_INSTALL_FAILED_PARSE_DISTRO_MODULETYPE_ERROR;
302 }
303 // parse ability
304 cJSON *abilityObjects = ParseValue(moduleObject, PROFILE_KEY_MODULE_ABILITIES, nullptr);
305 CHECK_NULL(abilityObjects, ERR_APPEXECFWK_INSTALL_FAILED_PARSE_ABILITIES_ERROR);
306 if (abilityObjects->type != cJSON_Array || cJSON_GetArraySize(abilityObjects) == 0) {
307 return ERR_APPEXECFWK_INSTALL_FAILED_PARSE_ABILITIES_ERROR;
308 }
309 return ParseAbilityInfo(abilityObjects, bundleProfile, bundleRes);
310 }
311
ParseAbilityInfo(const cJSON * abilityInfoObjects,BundleProfile & bundleProfile,BundleRes & bundleRes)312 uint8_t GtBundleParser::ParseAbilityInfo(const cJSON *abilityInfoObjects, BundleProfile &bundleProfile,
313 BundleRes &bundleRes)
314 {
315 cJSON *firstAbilityJson = cJSON_GetArrayItem(abilityInfoObjects, 0);
316 bundleProfile.label = ParseValue(firstAbilityJson, PROFILE_KEY_MODULE_ABILITY_LABEL);
317 CHECK_NULL(bundleProfile.label, ERR_APPEXECFWK_INSTALL_FAILED_PARSE_ABILITY_LABEL_ERROR);
318
319 bundleRes.abilityRes = reinterpret_cast<AbilityRes *>(AdapterMalloc(sizeof(AbilityRes)));
320 bundleRes.totalNumOfAbilityRes = 1;
321 CHECK_NULL(bundleRes.abilityRes, ERR_APPEXECFWK_INSTALL_FAILED_INTERNAL_ERROR);
322 if (memset_s(bundleRes.abilityRes, sizeof(AbilityRes), 0, sizeof(AbilityRes)) != EOK) {
323 return ERR_APPEXECFWK_INSTALL_FAILED_INTERNAL_ERROR;
324 }
325
326 if (BundleUtil::StartWith(bundleProfile.label, DEFAULT_LABEL_SETTING)) {
327 int32_t labelId = ParseValue(firstAbilityJson, LABEL_ID, -1);
328 if (labelId < 0) {
329 return ERR_APPEXECFWK_INSTALL_FAILED_PARSE_ABILITY_LABEL_ERROR;
330 }
331 bundleRes.abilityRes->labelId = labelId;
332 }
333 CHECK_LENGTH(strlen(bundleProfile.label), MAX_LABLE_LEN,
334 ERR_APPEXECFWK_INSTALL_FAILED_EXCEED_MAX_LABEL_LENGTH_ERROR);
335
336 bundleProfile.iconPath = ParseValue(firstAbilityJson, PROFILE_KEY_MODULE_ABILITY_ICON);
337 CHECK_NULL(bundleProfile.iconPath, ERR_APPEXECFWK_INSTALL_FAILED_PARSE_ABILITY_ICONPATH_ERROR);
338 if (strcmp(bundleProfile.iconPath, DEFAULT_ICON_SETTING) != 0) {
339 return ERR_APPEXECFWK_INSTALL_FAILED_PARSE_ABILITY_ICONPATH_ERROR;
340 }
341 int32_t iconId = ParseValue(firstAbilityJson, ICON_ID, -1);
342 if (iconId < 0) {
343 return ERR_APPEXECFWK_INSTALL_FAILED_PARSE_ABILITY_ICONPATH_ERROR;
344 }
345 bundleRes.abilityRes->iconId = iconId;
346 if (cJSON_HasObjectItem(firstAbilityJson, PROFILE_KEY_MODULE_ABILITY_SRC_PATH)) {
347 bundleProfile.srcPath = ParseValue(firstAbilityJson, PROFILE_KEY_MODULE_ABILITY_SRC_PATH);
348 CHECK_NULL(bundleProfile.srcPath, ERR_APPEXECFWK_INSTALL_FAILED_PARSE_ABILITY_SRC_PATH_ERROR);
349 }
350 return ParseAllAbilityInfo(abilityInfoObjects, bundleProfile);
351 }
352
ParseAllAbilityInfo(const cJSON * abilityObjects,BundleProfile & bundleProfile)353 uint8_t GtBundleParser::ParseAllAbilityInfo(const cJSON *abilityObjects, BundleProfile &bundleProfile)
354 {
355 const uint32_t MAX_ABILITY_NUM = 16;
356 uint32_t abilityNum = cJSON_GetArraySize(abilityObjects);
357 if (abilityNum == 0) {
358 return ERR_OK;
359 }
360 if (abilityNum > MAX_ABILITY_NUM) {
361 HILOG_ERROR(
362 HILOG_MODULE_AAFWK, "too many abilityInfos, (cur:%{public}d/max:%{public}d", abilityNum, MAX_ABILITY_NUM);
363 return ERR_APPEXECFWK_INSTALL_FAILED_PARSE_ABILITIES_ERROR;
364 }
365 uint32_t sizeInByte = abilityNum * sizeof(AbilityInfo);
366 AbilityInfo *abilityInfoPtr = reinterpret_cast<AbilityInfo *>(AdapterMalloc(sizeInByte));
367 if (abilityInfoPtr == nullptr || memset_s(abilityInfoPtr, sizeInByte, 0, sizeInByte) != EOK) {
368 HILOG_ERROR(HILOG_MODULE_AAFWK, "abilityInfos alloc memory fail");
369 AdapterFree(abilityInfoPtr);
370 return ERR_APPEXECFWK_SYSTEM_INTERNAL_ERROR;
371 }
372 bundleProfile.numOfAbility = abilityNum;
373 bundleProfile.abilityInfos = abilityInfoPtr;
374 const cJSON *object = nullptr;
375 cJSON_ArrayForEach(object, abilityObjects) {
376 abilityInfoPtr->bundleName = bundleProfile.bundleName;
377 uint8_t errorCode = ParsePerAbilityInfo(object, *abilityInfoPtr++);
378 CHECK_IS_TRUE((errorCode == ERR_OK), errorCode);
379 }
380 return ERR_OK;
381 }
ParsePerAbilityInfo(const cJSON * abilityObjects,AbilityInfo & abilityInfo)382 uint8_t GtBundleParser::ParsePerAbilityInfo(const cJSON *abilityObjects, AbilityInfo &abilityInfo)
383 {
384 HILOG_INFO(HILOG_MODULE_AAFWK, "[BMS] start parse skill and metadata");
385 uint8_t errorCode = ParseAbilitySkills(abilityObjects, abilityInfo);
386 if (errorCode != ERR_OK) {
387 return errorCode;
388 }
389 return ParseMetaData(abilityObjects, abilityInfo.metaData, METADATA_SIZE);
390 }
ParseMetaData(const cJSON * moduleObject,MetaData * metaData[],int maxCount)391 uint8_t GtBundleParser::ParseMetaData(const cJSON *moduleObject, MetaData *metaData[], int maxCount)
392 {
393 HILOG_INFO(HILOG_MODULE_AAFWK, "[BMS] start parse metadata");
394 cJSON *object = ParseValue(moduleObject, PROFILE_KEY_MODULE_METADATA, nullptr);
395 // if no metadata, return ERR_OK
396 if (object == nullptr || object->type == cJSON_NULL) {
397 return ERR_OK;
398 }
399 object = cJSON_GetObjectItem(object, PROFILE_KEY_MODULE_METADATA_CUSTOMIZEDATA);
400 if (object == nullptr || object->type == cJSON_NULL) {
401 return ERR_OK;
402 }
403 CHECK_IS_TRUE((cJSON_IsArray(object) && (cJSON_GetArraySize(object) <= maxCount)),
404 ERR_APPEXECFWK_INSTALL_FAILED_PARSE_METADATA_ERROR);
405
406 int32_t i = 0;
407 cJSON *objectItem = nullptr;
408 cJSON_ArrayForEach(objectItem, object)
409 {
410 metaData[i] = reinterpret_cast<MetaData *>(AdapterMalloc(sizeof(MetaData)));
411 if (metaData[i] == nullptr || memset_s(metaData[i], sizeof(MetaData), 0, sizeof(MetaData)) != EOK) {
412 HILOG_ERROR(HILOG_MODULE_AAFWK, "mallco metadate fail");
413 return ERR_APPEXECFWK_SYSTEM_INTERNAL_ERROR;
414 }
415 if (cJSON_HasObjectItem(objectItem, PROFILE_KEY_MODULE_METADATA_NAME)) {
416 metaData[i]->name = Utils::Strdup(ParseValue(objectItem, PROFILE_KEY_MODULE_METADATA_NAME));
417 CHECK_NULL(metaData[i]->name, ERR_APPEXECFWK_INSTALL_FAILED_PARSE_METADATA_ERROR);
418 CHECK_LENGTH(strlen(metaData[i]->name),
419 MAX_METADATA_NAME,
420 ERR_APPEXECFWK_INSTALL_FAILED_EXCEED_MAX_METADATA_NAME_LENGTH_ERROR);
421 }
422
423 if (cJSON_HasObjectItem(objectItem, PROFILE_KEY_MODULE_METADATA_VALUE)) {
424 metaData[i]->value = Utils::Strdup(ParseValue(objectItem, PROFILE_KEY_MODULE_METADATA_VALUE));
425 CHECK_NULL(metaData[i]->value, ERR_APPEXECFWK_INSTALL_FAILED_PARSE_METADATA_ERROR);
426 CHECK_LENGTH(strlen(metaData[i]->value),
427 MAX_METADATA_VALUE,
428 ERR_APPEXECFWK_INSTALL_FAILED_EXCEED_MAX_METADATA_VALUE_LENGTH_ERROR);
429 }
430
431 if (cJSON_HasObjectItem(objectItem, PROFILE_KEY_MODULE_METADATA_EXTRA)) {
432 metaData[i]->extra = Utils::Strdup(ParseValue(objectItem, PROFILE_KEY_MODULE_METADATA_EXTRA));
433 CHECK_NULL(metaData[i]->extra, ERR_APPEXECFWK_INSTALL_FAILED_PARSE_METADATA_ERROR);
434 }
435 i++;
436 }
437 HILOG_INFO(HILOG_MODULE_AAFWK, "[BMS] end parse metadata");
438 return ERR_OK;
439 }
ParseAbilitySkills(const cJSON * abilityObjectItem,AbilityInfo & abilityInfo)440 uint8_t GtBundleParser::ParseAbilitySkills(const cJSON *abilityObjectItem, AbilityInfo &abilityInfo)
441 {
442 HILOG_INFO(HILOG_MODULE_AAFWK, "[BMS] start parse skills");
443 cJSON *skillsObject = ParseValue(abilityObjectItem, PROFILE_KEY_SKILLS, nullptr);
444 if (skillsObject == nullptr) {
445 return ERR_OK;
446 }
447 CHECK_IS_TRUE((cJSON_IsArray(skillsObject) && (cJSON_GetArraySize(skillsObject) <= SKILL_SIZE)),
448 ERR_APPEXECFWK_INSTALL_FAILED_PARSE_SKILLS_ERROR);
449
450 int32_t i = 0;
451 cJSON *object = nullptr;
452 cJSON_ArrayForEach(object, skillsObject)
453 {
454 Skill *skillPtr = reinterpret_cast<Skill *>(AdapterMalloc(sizeof(Skill)));
455 if (skillPtr == nullptr || memset_s(skillPtr, sizeof(Skill), 0, sizeof(Skill)) != EOK) {
456 HILOG_ERROR(HILOG_MODULE_AAFWK, "mallco metadate fail");
457 return ERR_APPEXECFWK_SYSTEM_INTERNAL_ERROR;
458 }
459 if (ParseOneSkill(object, *skillPtr) != ERR_OK) {
460 AdapterFree(skillPtr);
461 return ERR_APPEXECFWK_INSTALL_FAILED_PARSE_SKILLS_ERROR;
462 }
463 abilityInfo.skills[i++] = skillPtr;
464 }
465 HILOG_INFO(HILOG_MODULE_AAFWK, "[BMS] end parse skills");
466 return ERR_OK;
467 }
468
ParseOneSkill(const cJSON * skillObject,Skill & skill)469 uint8_t GtBundleParser::ParseOneSkill(const cJSON *skillObject, Skill &skill)
470 {
471 HILOG_INFO(HILOG_MODULE_AAFWK, "[BMS] start parse one skill");
472 cJSON *entities = ParseValue(skillObject, PROFILE_KEY_SKILLS_ENTITIES, nullptr);
473 cJSON *actions = ParseValue(skillObject, PROFILE_KEY_SKILLS_ACTIONS, nullptr);
474 if (entities == nullptr && actions == nullptr) {
475 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] entities and actions is invalid");
476 return ERR_APPEXECFWK_INSTALL_FAILED_PARSE_SKILLS_ERROR;
477 }
478 int entitiesCount = cJSON_GetArraySize(entities);
479 int actionsCount = cJSON_GetArraySize(actions);
480 if (entitiesCount > MAX_SKILL_ITEM || actionsCount > MAX_SKILL_ITEM) {
481 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] too many skills or actions configuredd");
482 return ERR_APPEXECFWK_INSTALL_FAILED_PARSE_SKILLS_ERROR;
483 }
484 int32_t i = 0;
485 cJSON *object = nullptr;
486 cJSON_ArrayForEach(object, entities)
487 {
488 if (!cJSON_IsString(object)) {
489 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] a string is expected in entities");
490 return ERR_APPEXECFWK_INSTALL_FAILED_PARSE_SKILLS_ERROR;
491 }
492 skill.entities[i++] = Utils::Strdup(object->valuestring);
493 }
494 i = 0;
495 object = nullptr;
496 cJSON_ArrayForEach(object, actions)
497 {
498 if (!cJSON_IsString(object)) {
499 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] a string is expected in actions");
500 return ERR_APPEXECFWK_INSTALL_FAILED_PARSE_SKILLS_ERROR;
501 }
502 skill.actions[i++] = Utils::Strdup(object->valuestring);
503 }
504 HILOG_INFO(HILOG_MODULE_AAFWK, "[BMS] end parse one skill");
505 return ERR_OK;
506 }
507
CheckDeviceTypeIsValid(const cJSON * deviceTypeObject)508 bool GtBundleParser::CheckDeviceTypeIsValid(const cJSON *deviceTypeObject)
509 {
510 if (!cJSON_IsArray(deviceTypeObject)) {
511 return false;
512 }
513
514 const char *deviceType = GetDeviceType();
515 if (deviceType == nullptr) {
516 return false;
517 }
518
519 cJSON *object = nullptr;
520 cJSON_ArrayForEach(object, deviceTypeObject) {
521 if (object->type != cJSON_String) {
522 return false;
523 }
524 if ((object->valuestring != nullptr) && (strcmp(object->valuestring, deviceType) == 0 ||
525 (strcmp(object->valuestring, DEFAULT_DEVICE_TYPE) == 0))) {
526 return true;
527 }
528 }
529 return false;
530 }
531
ParseModuleMetaData(const cJSON * moduleObject,BundleProfile & bundleProfile)532 uint8_t GtBundleParser::ParseModuleMetaData(const cJSON *moduleObject, BundleProfile &bundleProfile)
533 {
534 cJSON *object = ParseValue(moduleObject, PROFILE_KEY_MODULE_METADATA, nullptr);
535 if (object == nullptr || object->type == cJSON_NULL) {
536 return ERR_OK;
537 }
538
539 object = cJSON_GetObjectItem(object, PROFILE_KEY_MODULE_METADATA_CUSTOMIZEDATA);
540 if (object == nullptr || object->type == cJSON_NULL) {
541 return ERR_OK;
542 }
543 int32_t size = cJSON_GetArraySize(object);
544 if (object->type != cJSON_Array || size > METADATA_SIZE) {
545 return ERR_APPEXECFWK_INSTALL_FAILED_PARSE_METADATA_ERROR;
546 }
547 cJSON *objectItem = nullptr;
548 int32_t i = 0;
549 cJSON_ArrayForEach(objectItem, object) {
550 bundleProfile.moduleInfo.metaData[i] = reinterpret_cast<MetaData *>
551 (AdapterMalloc(sizeof(MetaData)));
552 if (bundleProfile.moduleInfo.metaData[i] == nullptr ||
553 memset_s(bundleProfile.moduleInfo.metaData[i], sizeof(MetaData), 0, sizeof(MetaData)) != EOK) {
554 return ERR_APPEXECFWK_INSTALL_FAILED_PARSE_METADATA_ERROR;
555 }
556 if (cJSON_HasObjectItem(objectItem, PROFILE_KEY_MODULE_METADATA_NAME)) {
557 bundleProfile.moduleInfo.metaData[i]->name = ParseValue(objectItem, PROFILE_KEY_MODULE_METADATA_NAME);
558 CHECK_NULL(bundleProfile.moduleInfo.metaData[i]->name,
559 ERR_APPEXECFWK_INSTALL_FAILED_PARSE_METADATA_ERROR);
560 CHECK_LENGTH(strlen(bundleProfile.moduleInfo.metaData[i]->name), MAX_METADATA_NAME,
561 ERR_APPEXECFWK_INSTALL_FAILED_EXCEED_MAX_METADATA_NAME_LENGTH_ERROR);
562 }
563
564 if (cJSON_HasObjectItem(objectItem, PROFILE_KEY_MODULE_METADATA_VALUE)) {
565 bundleProfile.moduleInfo.metaData[i]->value = ParseValue(objectItem, PROFILE_KEY_MODULE_METADATA_VALUE);
566 CHECK_NULL(bundleProfile.moduleInfo.metaData[i]->value,
567 ERR_APPEXECFWK_INSTALL_FAILED_PARSE_METADATA_ERROR);
568 CHECK_LENGTH(strlen(bundleProfile.moduleInfo.metaData[i]->value), MAX_METADATA_VALUE,
569 ERR_APPEXECFWK_INSTALL_FAILED_EXCEED_MAX_METADATA_VALUE_LENGTH_ERROR);
570 }
571
572 if (cJSON_HasObjectItem(objectItem, PROFILE_KEY_MODULE_METADATA_EXTRA)) {
573 bundleProfile.moduleInfo.metaData[i]->extra = ParseValue(objectItem, PROFILE_KEY_MODULE_METADATA_EXTRA);
574 CHECK_NULL(bundleProfile.moduleInfo.metaData[i]->extra,
575 ERR_APPEXECFWK_INSTALL_FAILED_PARSE_METADATA_ERROR);
576 }
577 i++;
578 }
579 return ERR_OK;
580 }
581
CreateBundleInfo(const char * path,const BundleProfile & bundleProfile,const BundleRes & bundleRes)582 BundleInfo *GtBundleParser::CreateBundleInfo(const char *path, const BundleProfile &bundleProfile,
583 const BundleRes &bundleRes)
584 {
585 BundleInfo *bundleInfo = reinterpret_cast<BundleInfo *>(AdapterMalloc(sizeof(BundleInfo)));
586 if (bundleInfo == nullptr) {
587 return nullptr;
588 }
589
590 if (memset_s(bundleInfo, sizeof(BundleInfo), 0, sizeof(BundleInfo)) != EOK) {
591 AdapterFree(bundleInfo);
592 return nullptr;
593 }
594
595 char *installedPath = Utils::Strdup(path);
596 if (!SetBundleInfo(installedPath, bundleProfile, bundleRes, bundleInfo)) {
597 BundleInfoUtils::FreeBundleInfo(bundleInfo);
598 return nullptr;
599 }
600 #ifdef _MINI_BMS_PERMISSION_
601 RefreshAllServiceTimeStamp();
602 #endif
603 uint8_t errorCode = ConvertResInfoToBundleInfo(path, bundleRes.abilityRes->labelId, bundleRes.abilityRes->iconId,
604 bundleInfo);
605 if (errorCode != ERR_OK) {
606 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] convert res to bundle info failed!");
607 BundleInfoUtils::FreeBundleInfo(bundleInfo);
608 return nullptr;
609 }
610 // get js path
611 char *jsPath = nullptr;
612 if (bundleProfile.srcPath == nullptr) {
613 char *jsPathComp[] = {bundleInfo->codePath, const_cast<char *>(ASSET_JS_PATH)};
614 jsPath = BundleUtil::Strscat(jsPathComp, sizeof(jsPathComp) / sizeof(char *));
615 } else {
616 char *jsPathComp[] = {bundleInfo->codePath, const_cast<char *>(ASSET_PATH), bundleProfile.srcPath};
617 jsPath = BundleUtil::Strscat(jsPathComp, sizeof(jsPathComp) / sizeof(char *));
618 }
619 if (jsPath == nullptr) {
620 BundleInfoUtils::FreeBundleInfo(bundleInfo);
621 return nullptr;
622 }
623
624 // set abilityInfo
625 AbilityInfo abilityInfo = {.srcPath = jsPath, .bundleName = bundleInfo->bundleName};
626 #ifdef _MINI_BMS_PARSE_METADATA_
627 if (!BundleInfoUtils::SetBundleInfoAbilityInfo(bundleInfo, abilityInfo, bundleProfile)) {
628 AdapterFree(abilityInfo.srcPath);
629 BundleInfoUtils::FreeBundleInfo(bundleInfo);
630 return nullptr;
631 }
632 #else
633 if (!BundleInfoUtils::SetBundleInfoAbilityInfo(bundleInfo, abilityInfo)) {
634 AdapterFree(abilityInfo.srcPath);
635 BundleInfoUtils::FreeBundleInfo(bundleInfo);
636 return nullptr;
637 }
638 #endif
639 AdapterFree(abilityInfo.srcPath);
640 return bundleInfo;
641 }
642
ConvertResInfoToBundleInfo(const char * path,uint32_t labelId,uint32_t iconId,BundleInfo * bundleInfo)643 uint8_t GtBundleParser::ConvertResInfoToBundleInfo(const char *path, uint32_t labelId, uint32_t iconId,
644 BundleInfo *bundleInfo)
645 {
646 if (path == nullptr || bundleInfo == nullptr) {
647 return ERR_APPEXECFWK_INSTALL_FAILED_INTERNAL_ERROR;
648 }
649 char *resPathComp[] = {
650 const_cast<char *>(path), const_cast<char *>(ASSETS), bundleInfo->moduleInfos[0].moduleName,
651 const_cast<char *>(RESOURCES_INDEX)
652 };
653 char *resPath = BundleUtil::Strscat(resPathComp, sizeof(resPathComp) / sizeof(char *));
654 if (resPath == nullptr) {
655 return ERR_APPEXECFWK_INSTALL_FAILED_INTERNAL_ERROR;
656 }
657 if (!BundleUtil::IsFile(resPath)) {
658 AdapterFree(resPath);
659 return ERR_APPEXECFWK_INSTALL_FAILED_RESOURCE_INDEX_NOT_EXISTS;
660 }
661 if (labelId != 0) {
662 char *label = nullptr;
663 if (GLOBAL_GetValueById(labelId, resPath, &label) != 0) {
664 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] global get label failed!");
665 Free(label);
666 AdapterFree(resPath);
667 return ERR_APPEXECFWK_INSTALL_FAILED_PARSE_LABEL_RES_ERROR;
668 }
669 // release label memory first
670 AdapterFree(bundleInfo->label);
671 bundleInfo->label = Utils::Strdup(label);
672 Free(label);
673 if (bundleInfo->label == nullptr) {
674 AdapterFree(resPath);
675 return ERR_APPEXECFWK_INSTALL_FAILED_INTERNAL_ERROR;
676 }
677 }
678 if (!ConvertIconResToBundleInfo(resPath, iconId, bundleInfo)) {
679 AdapterFree(resPath);
680 return ERR_APPEXECFWK_INSTALL_FAILED_PARSE_ICON_RES_ERROR;
681 }
682 AdapterFree(resPath);
683 return ERR_OK;
684 }
685
ConvertIconResToBundleInfo(const char * resPath,uint32_t iconId,BundleInfo * bundleInfo)686 bool GtBundleParser::ConvertIconResToBundleInfo(const char *resPath, uint32_t iconId, BundleInfo *bundleInfo)
687 {
688 if (resPath == nullptr || bundleInfo == nullptr || iconId == 0) {
689 return false;
690 }
691
692 char *relativeIconPath = nullptr;
693 if (GLOBAL_GetValueById(iconId, const_cast<char *>(resPath), &relativeIconPath) != 0) {
694 HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] global get icon failed!");
695 return false;
696 }
697 // set relativeIconDir
698 if (relativeIconPath == nullptr) {
699 return false;
700 }
701 char *pos = relativeIconPath + strlen(relativeIconPath);
702 for (; *pos != '/'; pos--) {};
703 *pos = '\0';
704 char *bigIconPathComp[] = {
705 bundleInfo->codePath, const_cast<char *>(ASSETS), relativeIconPath, const_cast<char *>(ICON_NAME)
706 };
707 char *smallIconPathComp[] = {
708 bundleInfo->codePath, const_cast<char *>(ASSETS), relativeIconPath, const_cast<char *>(SMALL_ICON_NAME)
709 };
710 char *bigIconPath = BundleUtil::Strscat(bigIconPathComp, sizeof(bigIconPathComp) / sizeof(char *));
711 if (bigIconPath == nullptr) {
712 Free(relativeIconPath);
713 return false;
714 }
715 char *smallIconPath = BundleUtil::Strscat(smallIconPathComp, sizeof(smallIconPathComp) / sizeof(char *));
716 if (smallIconPath == nullptr) {
717 Free(relativeIconPath);
718 AdapterFree(bigIconPath);
719 return false;
720 }
721
722 char *bigIconPngPathComp[] = {
723 bundleInfo->codePath, const_cast<char *>(ASSETS), relativeIconPath, const_cast<char *>(ICON_PNG_NAME)
724 };
725 char *smallIconPngPathComp[] = {
726 bundleInfo->codePath, const_cast<char *>(ASSETS), relativeIconPath, const_cast<char *>(SMALL_ICON_PNG_NAME)
727 };
728 char *bigIconPngPath = BundleUtil::Strscat(bigIconPngPathComp, sizeof(bigIconPngPathComp) / sizeof(char *));
729 if (bigIconPngPath == nullptr) {
730 Free(relativeIconPath);
731 return false;
732 }
733 char *smallIconPngPath = BundleUtil::Strscat(smallIconPngPathComp, sizeof(smallIconPngPathComp) / sizeof(char *));
734 if (smallIconPngPath == nullptr) {
735 Free(relativeIconPath);
736 AdapterFree(bigIconPngPath);
737 return false;
738 }
739 Free(relativeIconPath);
740 bool isBigIconExisted = BundleUtil::IsFile(bigIconPath);
741 bool isSmallIconExisted = BundleUtil::IsFile(smallIconPath);
742 if ((!isBigIconExisted && !BundleUtil::IsFile(bigIconPngPath))||
743 (!isSmallIconExisted && !BundleUtil::IsFile(smallIconPngPath))) {
744 AdapterFree(bigIconPath);
745 AdapterFree(smallIconPath);
746 AdapterFree(bigIconPngPath);
747 AdapterFree(smallIconPngPath);
748 return false;
749 }
750 // release bigIconPath and smallIconPath memory in bundleInfo first
751 AdapterFree(bundleInfo->bigIconPath);
752 AdapterFree(bundleInfo->smallIconPath);
753 if (isBigIconExisted) {
754 bundleInfo->bigIconPath = bigIconPath;
755 AdapterFree(bigIconPngPath);
756 } else {
757 bundleInfo->bigIconPath = bigIconPngPath;
758 AdapterFree(bigIconPath);
759 }
760 if (isSmallIconExisted) {
761 bundleInfo->smallIconPath = smallIconPath;
762 AdapterFree(smallIconPngPath);
763 } else {
764 bundleInfo->smallIconPath = smallIconPngPath;
765 AdapterFree(smallIconPath);
766 }
767 return true;
768 }
769
ParseHapProfile(int32_t fp,uint32_t fileSize,Permissions & permissions,BundleRes & bundleRes,BundleInfo ** bundleInfo)770 uint8_t GtBundleParser::ParseHapProfile(int32_t fp, uint32_t fileSize, Permissions &permissions, BundleRes &bundleRes,
771 BundleInfo **bundleInfo)
772 {
773 char *profileStr = GtBundleExtractor::ExtractHapProfile(fp, fileSize);
774 if (profileStr == nullptr) {
775 return ERR_APPEXECFWK_INSTALL_FAILED_PARSE_PROFILE_ERROR;
776 }
777
778 cJSON *root = cJSON_Parse(profileStr);
779 if (root == nullptr) {
780 AdapterFree(profileStr);
781 return ERR_APPEXECFWK_INSTALL_FAILED_PARSE_PROFILE_ERROR;
782 }
783 AdapterFree(profileStr);
784
785 cJSON *appObject = cJSON_GetObjectItem(root, PROFILE_KEY_APP);
786 cJSON *configObject = cJSON_GetObjectItem(root, PROFILE_KEY_DEVICECONFIG);
787 cJSON *moduleObject = cJSON_GetObjectItem(root, PROFILE_KEY_MODULE);
788 if (appObject == nullptr || moduleObject == nullptr) {
789 cJSON_Delete(root);
790 return ERR_APPEXECFWK_INSTALL_FAILED_PARSE_PROFILE_ERROR;
791 }
792
793 BundleProfile bundleProfile;
794 if (memset_s(&bundleProfile, sizeof(BundleProfile), 0, sizeof(BundleProfile)) != EOK) {
795 cJSON_Delete(root);
796 return ERR_APPEXECFWK_SYSTEM_INTERNAL_ERROR;
797 }
798
799 uint8_t errorCode = ParseJsonInfo(appObject, configObject, moduleObject, bundleProfile, bundleRes);
800 CHECK_PARSE_RESULT(errorCode, root, bundleProfile, bundleRes);
801
802 cJSON *object = ParseValue(moduleObject, PROFILE_KEY_REQPERMISSIONS, nullptr);
803 errorCode = ParsePermissions(object, permissions);
804 CHECK_PARSE_RESULT(errorCode, root, bundleProfile, bundleRes);
805
806 errorCode = SaveBundleInfo(bundleProfile, bundleRes, bundleInfo);
807 CHECK_PARSE_RESULT(errorCode, root, bundleProfile, bundleRes);
808
809 FREE_BUNDLE_PROFILE(bundleProfile);
810 cJSON_Delete(root);
811 return ERR_OK;
812 }
813
SaveBundleInfo(const BundleProfile & bundleProfile,const BundleRes & bundleRes,BundleInfo ** bundleInfo)814 uint8_t GtBundleParser::SaveBundleInfo(const BundleProfile &bundleProfile, const BundleRes &bundleRes,
815 BundleInfo **bundleInfo)
816 {
817 int32_t len = strlen(INSTALL_PATH) + 1 + strlen(bundleProfile.bundleName) + 1;
818 char *installedPath = reinterpret_cast<char *>(AdapterMalloc(len));
819 if (installedPath == nullptr) {
820 return ERR_APPEXECFWK_INSTALL_FAILED_INTERNAL_ERROR;
821 }
822 if (sprintf_s(installedPath, len, "%s/%s", INSTALL_PATH, bundleProfile.bundleName) < 0) {
823 AdapterFree(installedPath);
824 return ERR_APPEXECFWK_INSTALL_FAILED_INTERNAL_ERROR;
825 }
826
827 *bundleInfo = reinterpret_cast<BundleInfo *>(AdapterMalloc(sizeof(BundleInfo)));
828 if (*bundleInfo == nullptr) {
829 AdapterFree(installedPath);
830 return ERR_APPEXECFWK_INSTALL_FAILED_INTERNAL_ERROR;
831 }
832
833 if (memset_s(*bundleInfo, sizeof(BundleInfo), 0, sizeof(BundleInfo)) != EOK) {
834 AdapterFree(*bundleInfo);
835 *bundleInfo = nullptr;
836 AdapterFree(installedPath);
837 return ERR_APPEXECFWK_INSTALL_FAILED_INTERNAL_ERROR;
838 }
839
840 if (!SetBundleInfo(installedPath, bundleProfile, bundleRes, *bundleInfo)) {
841 BundleInfoUtils::FreeBundleInfo(*bundleInfo);
842 *bundleInfo = nullptr;
843 return ERR_APPEXECFWK_INSTALL_FAILED_INTERNAL_ERROR;
844 }
845 char *jsPath = nullptr;
846 if (bundleProfile.srcPath == nullptr) {
847 char *jsPathComp[] = {(*bundleInfo)->codePath, const_cast<char *>(ASSET_JS_PATH)};
848 jsPath = BundleUtil::Strscat(jsPathComp, sizeof(jsPathComp) / sizeof(char *));
849 } else {
850 char *jsPathComp[] = {(*bundleInfo)->codePath, const_cast<char *>(ASSET_PATH), bundleProfile.srcPath};
851 jsPath = BundleUtil::Strscat(jsPathComp, sizeof(jsPathComp) / sizeof(char *));
852 }
853 if (jsPath == nullptr) {
854 BundleInfoUtils::FreeBundleInfo(*bundleInfo);
855 *bundleInfo = nullptr;
856 return ERR_APPEXECFWK_INSTALL_FAILED_INTERNAL_ERROR;
857 }
858
859 AbilityInfo abilityInfo = {.srcPath = jsPath, .bundleName = (*bundleInfo)->bundleName};
860 // set abilityInfo
861 #ifdef _MINI_BMS_PARSE_METADATA_
862 if (!BundleInfoUtils::SetBundleInfoAbilityInfo(*bundleInfo, abilityInfo, bundleProfile)) {
863 AdapterFree(jsPath);
864 BundleInfoUtils::FreeBundleInfo(*bundleInfo);
865 *bundleInfo = nullptr;
866 return ERR_APPEXECFWK_INSTALL_FAILED_INTERNAL_ERROR;
867 }
868 #else
869 if (!BundleInfoUtils::SetBundleInfoAbilityInfo(*bundleInfo, abilityInfo)) {
870 AdapterFree(jsPath);
871 BundleInfoUtils::FreeBundleInfo(*bundleInfo);
872 *bundleInfo = nullptr;
873 return ERR_APPEXECFWK_INSTALL_FAILED_INTERNAL_ERROR;
874 }
875 #endif
876 AdapterFree(jsPath);
877 return ERR_OK;
878 }
879
SetBundleInfo(const char * installedPath,const BundleProfile & bundleProfile,const BundleRes & bundleRes,BundleInfo * bundleInfo)880 bool GtBundleParser::SetBundleInfo(const char *installedPath, const BundleProfile &bundleProfile,
881 const BundleRes &bundleRes, BundleInfo *bundleInfo)
882 {
883 if (bundleInfo == nullptr || bundleRes.abilityRes == nullptr || installedPath == nullptr) {
884 return false;
885 }
886
887 bundleInfo->versionCode = bundleProfile.profileVersion.versionCode;
888 bundleInfo->compatibleApi = bundleProfile.profileApiVersion.minApiVersion;
889 bundleInfo->targetApi = bundleProfile.profileApiVersion.maxApiVersion;
890 bundleInfo->codePath = const_cast<char *>(installedPath);
891
892 int32_t len = strlen(DATA_PATH) + 1 + strlen(bundleProfile.bundleName) + 1;
893 char *dataPath = reinterpret_cast<char *>(UI_Malloc(len));
894 if (dataPath == nullptr) {
895 return false;
896 }
897 if (sprintf_s(dataPath, len, "%s/%s", DATA_PATH, bundleProfile.bundleName) < 0) {
898 UI_Free(dataPath);
899 return false;
900 }
901
902 bundleInfo->dataPath = Utils::Strdup(dataPath);
903 UI_Free(dataPath);
904 if (bundleInfo->dataPath == nullptr) {
905 return false;
906 }
907
908 if (bundleProfile.vendor != nullptr && !BundleInfoUtils::SetBundleInfoVendor(bundleInfo, bundleProfile.vendor)) {
909 return false;
910 }
911
912 if (bundleRes.abilityRes->labelId == 0 && bundleProfile.label != nullptr &&
913 !BundleInfoUtils::SetBundleInfoLabel(bundleInfo, bundleProfile.label)) {
914 return false;
915 }
916
917 if (!BundleInfoUtils::SetBundleInfoBundleName(bundleInfo, bundleProfile.bundleName) ||
918 !BundleInfoUtils::SetBundleInfoVersionName(bundleInfo, bundleProfile.profileVersion.versionName) ||
919 !SetModuleInfos(bundleProfile, bundleInfo)) {
920 return false;
921 }
922 return true;
923 }
924
SetModuleInfos(const BundleProfile & bundleProfile,BundleInfo * bundleInfo)925 bool GtBundleParser::SetModuleInfos(const BundleProfile &bundleProfile, BundleInfo *bundleInfo)
926 {
927 if (bundleInfo == nullptr) {
928 return false;
929 }
930 bundleInfo->moduleInfos = reinterpret_cast<ModuleInfo *>(AdapterMalloc(sizeof(ModuleInfo)));
931 if (bundleInfo->moduleInfos == nullptr) {
932 return false;
933 }
934
935 if (memset_s(bundleInfo->moduleInfos, sizeof(ModuleInfo), 0, sizeof(ModuleInfo)) != EOK) {
936 AdapterFree(bundleInfo->moduleInfos);
937 return false;
938 }
939
940 bundleInfo->numOfModule = 1;
941 if (!ModuleInfoUtils::SetModuleInfoMetaData(bundleInfo->moduleInfos,
942 const_cast<MetaData **>(bundleProfile.moduleInfo.metaData), METADATA_SIZE)) {
943 return false;
944 }
945 if (!ModuleInfoUtils::SetModuleInfoModuleName(bundleInfo->moduleInfos, bundleProfile.moduleInfo.moduleName)) {
946 return false;
947 }
948 return true;
949 }
950
ParsePermissions(const cJSON * object,Permissions & permissions)951 uint8_t GtBundleParser::ParsePermissions(const cJSON *object, Permissions &permissions)
952 {
953 if (object == nullptr) {
954 return ERR_OK;
955 }
956
957 if (object->type != cJSON_Array) {
958 return ERR_APPEXECFWK_INSTALL_FAILED_PARSE_PERMISSIONS_ERROR;
959 }
960 permissions.permNum = cJSON_GetArraySize(object);
961 if (permissions.permNum == 0) {
962 return ERR_OK;
963 }
964
965 permissions.permissionTrans = reinterpret_cast<PermissionTrans *>(UI_Malloc(sizeof(PermissionTrans) *
966 permissions.permNum));
967
968 if (permissions.permissionTrans == nullptr) {
969 return ERR_APPEXECFWK_INSTALL_FAILED_PARSE_PERMISSIONS_ERROR;
970 }
971
972 PermissionTrans *perms = permissions.permissionTrans;
973 cJSON *reqPermission = nullptr;
974 cJSON_ArrayForEach(reqPermission, object) {
975 if (!SetReqPermission(reqPermission, perms)) {
976 return ERR_APPEXECFWK_INSTALL_FAILED_PARSE_PERMISSIONS_ERROR;
977 }
978 perms++;
979 }
980 return ERR_OK;
981 }
982
SetReqPermission(const cJSON * object,PermissionTrans * permission)983 bool GtBundleParser::SetReqPermission(const cJSON *object, PermissionTrans *permission)
984 {
985 if (object == nullptr || permission == nullptr) {
986 return false;
987 }
988
989 char *name = ParseValue(object, PROFILE_KEY_REQPERMISSIONS_NAME);
990 char *desc = ParseValue(object, PROFILE_KEY_REQPERMISSIONS_REASON);
991 if (name == nullptr || desc == nullptr) {
992 return false;
993 }
994
995 if (strncpy_s(permission->name, sizeof(permission->name), name, strlen(name)) != EOK ||
996 strncpy_s(permission->desc, sizeof(permission->desc), desc, strlen(desc)) != EOK) {
997 return false;
998 }
999
1000 cJSON *usedSceneObject = ParseValue(object, PROFILE_KEY_REQPERMISSIONS_USEDSCENE, nullptr);
1001 char *when = ParseValue(usedSceneObject, PROFILE_KEY_REQPERMISSIONS_WHEN);
1002 if (when == nullptr) {
1003 return false;
1004 }
1005 if (strcmp(when, GRANTTIME_INUSE) == 0) {
1006 permission->when = INUSE;
1007 } else if (strcmp(when, GRANTTIME_ALWAYS) == 0) {
1008 permission->when = ALWAYS;
1009 } else {
1010 return false;
1011 }
1012 return true;
1013 }
1014 } // namespace OHOS