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