1 /*
2  * Copyright (c) 2020 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_util.h"
17 
18 #include <new>
19 
20 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
21 #include <dirent.h>
22 #include <fcntl.h>
23 #include <stdio.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <time.h>
27 #include <unistd.h>
28 #include "bundle_daemon_client.h"
29 #else
30 #include "adapter.h"
31 #include "bundlems_log.h"
32 #include "cstdio"
33 #include "dirent.h"
34 #include "fcntl.h"
35 #include "los_tick.h"
36 #include "sys/stat.h"
37 #include "unistd.h"
38 #endif
39 #include <cstdlib>
40 #include "utils.h"
41 
42 namespace OHOS {
43 const char DIGITSTR[] = "0123456789";
44 const uint8_t MAX_CHARACTER_VALUE = 26;
45 const uint8_t NUM_OF_TYPE = 3;
46 #ifdef __LITEOS_M__
47 const int32_t MAX_JSON_SIZE = 1024 * 64;
48 #else
49 const uint32_t MAX_JSON_SIZE = 1024 * 64;
50 #endif
51 
52 #ifdef __LITEOS_M__
53 #ifndef CONFIG_FT_MODE
CJsonBmsMalloc(size_t size)54 static void *CJsonBmsMalloc(size_t size)
55 {
56     return OhosMalloc(MEM_TYPE_CJSON_LSRAM, size);
57 }
58 
CJsonBmsFree(void * pointer)59 static void CJsonBmsFree(void *pointer)
60 {
61     OhosFree(pointer);
62 }
63 
OhosBmsCjsonHooksInit(void)64 static void OhosBmsCjsonHooksInit(void)
65 {
66     cJSON_Hooks hooks;
67     hooks.malloc_fn = CJsonBmsMalloc;
68     hooks.free_fn = CJsonBmsFree;
69     cJSON_InitHooks(&hooks);
70 }
71 #endif // CONFIG_FT_MODE
72 #endif // __LITEOS_M__
73 /*
74  * path should not include ".." or "./" or ".\0"
75  */
CheckRealPath(const char * path)76 bool BundleUtil::CheckRealPath(const char *path)
77 {
78     if (path == nullptr) {
79 #ifdef APP_PLATFORM_WATCHGT
80         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] CheckRealPath path null");
81 #endif
82         return false;
83     }
84     if (strlen(path) > PATH_LENGTH) {
85 #ifdef APP_PLATFORM_WATCHGT
86         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] CheckRealPath path too long:%d", strlen(path));
87 #endif
88         return false;
89     }
90     char *next = const_cast<char *>(path);
91     for (; *next != '\0'; next++) {
92         if (*next != '.') {
93             continue;
94         }
95         next++;
96         if (*next == '\0' || *next == '.' || *next == '/') {
97 #ifdef APP_PLATFORM_WATCHGT
98             HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] CheckRealPath path fail:%d", *next);
99 #endif
100             return false;
101         }
102     }
103     return true;
104 }
105 
IsFile(const char * path)106 bool BundleUtil::IsFile(const char *path)
107 {
108     if (!CheckRealPath(path)) {
109         return false;
110     }
111 
112     struct stat buf = { 0 };
113     int32_t ret = stat(path, &buf);
114     if (ret != 0) {
115         return false;
116     }
117 #ifdef __LITEOS_M__
118 #ifndef CONFIG_FT_MODE
119     OhosBmsCjsonHooksInit();
120 #endif
121 #endif
122     int32_t fp = open(path, O_RDONLY, S_IREAD | S_IWRITE);
123     if (fp >= 0) {
124         close(fp);
125         return true;
126     }
127     return false;
128 }
129 
IsDir(const char * path)130 bool BundleUtil::IsDir(const char *path)
131 {
132     if (path == nullptr) {
133         return false;
134     }
135 
136     struct stat buf = { 0 };
137     int32_t ret = stat(path, &buf);
138     if (ret != 0) {
139         return false;
140     }
141 #ifdef __LITEOS_M__
142 #ifndef CONFIG_FT_MODE
143     OhosBmsCjsonHooksInit();
144 #endif
145 #endif
146     if ((buf.st_mode & S_IFDIR) == S_IFDIR) {
147         return true;
148     }
149     return false;
150 }
151 
EndWith(const char * str,const char * subStr)152 bool BundleUtil::EndWith(const char *str, const char *subStr)
153 {
154     if (str == nullptr || subStr == nullptr) {
155         return false;
156     }
157 
158     int32_t strLen = strlen(str);
159     int32_t subStrLen = strlen(subStr);
160     if (strLen == 0 || subStrLen == 0 || strLen < subStrLen) {
161         return false;
162     }
163 
164     while (subStrLen >= 1) {
165         if (str[strLen - 1] != subStr[subStrLen - 1]) {
166             return false;
167         }
168         strLen--;
169         subStrLen--;
170     }
171     return true;
172 }
173 
StartWith(const char * str,const char * subStr)174 bool BundleUtil::StartWith(const char *str, const char *subStr)
175 {
176     if (str == nullptr || subStr == nullptr) {
177         return false;
178     }
179 
180     int32_t strLen = strlen(str);
181     int32_t subStrLen = strlen(subStr);
182     if (strLen == 0 || subStrLen == 0 || strLen < subStrLen) {
183         return false;
184     }
185 
186     int32_t index = 0;
187     while (index < subStrLen) {
188         if (str[index] != subStr[index]) {
189             return false;
190         }
191         index++;
192     }
193     return true;
194 }
195 
IsDigitStr(const char * str)196 bool BundleUtil::IsDigitStr(const char *str)
197 {
198     if (str == nullptr) {
199         return false;
200     }
201     return strspn(str, DIGITSTR) == strlen(str);
202 }
203 
GetFileSize(const char * filePath)204 uint32_t BundleUtil::GetFileSize(const char *filePath)
205 {
206     if (!CheckRealPath(filePath)) {
207         return 0;
208     }
209 
210     struct stat fileInfo;
211     int32_t ret = stat(filePath, &fileInfo);
212     if (ret != 0) {
213         return 0;
214     }
215 #ifdef __LITEOS_M__
216 #ifndef CONFIG_FT_MODE
217     OhosBmsCjsonHooksInit();
218 #endif
219 #endif
220     return fileInfo.st_size;
221 }
222 
GetFileFolderSize(const char * filePath)223 uint32_t BundleUtil::GetFileFolderSize(const char *filePath)
224 {
225     if (!CheckRealPath(filePath)) {
226         return 0;
227     }
228     List<char *>* list = new (std::nothrow)List<char *>();
229     if (list == nullptr) {
230 #ifdef APP_PLATFORM_WATCHGT
231         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] GetFolderSize failed, list is null");
232 #endif
233         return 0;
234     }
235 
236     list->PushFront(Utils::Strdup(filePath));
237     uint32_t fileFolderSize = 0;
238     while (!list->IsEmpty()) {
239         char *curPath = list->Front();
240         if (curPath == nullptr) {
241             break;
242         }
243         fileFolderSize += GetCurrentFolderSize(curPath, list);
244         list->PopFront();
245         AdapterFree(curPath);
246     }
247 
248     if (!list->IsEmpty()) {
249 #ifdef APP_PLATFORM_WATCHGT
250         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] After get folder size, list is still not empty");
251 #endif
252         for (auto node = list->Begin(); node != list->End(); node = node->next_) {
253             AdapterFree(node->value_);
254         }
255     }
256     delete list;
257     return fileFolderSize;
258 }
259 
GetCurrentFolderSize(const char * dirPath,List<char * > * list)260 uint32_t BundleUtil::GetCurrentFolderSize(const char *dirPath, List<char *>* list)
261 {
262     DIR *dir = nullptr;
263     if ((dir = opendir(dirPath)) == nullptr) {
264         return 0;
265     }
266     dirent *dp = nullptr;
267     char filePath[PATH_LENGTH] = { 0 };
268     struct stat buf = { 0 };
269     uint32_t fileSize = 0;
270     while ((dp = readdir(dir)) != nullptr) {
271         if ((strcmp(dp->d_name, ".") == 0) || (strcmp(dp->d_name, "..")) == 0) {
272             continue;
273         }
274 
275         if (memset_s(filePath, PATH_LENGTH, 0, PATH_LENGTH) != EOK) {
276             continue;
277         }
278 
279         if (sprintf_s(filePath, PATH_LENGTH, "%s/%s", dirPath, dp->d_name) < 0) {
280             continue;
281         }
282 
283         if (!IsDir(filePath)) {
284             if (stat(filePath, &buf) != 0 || buf.st_size <= 0) {
285                 fileSize = 0;
286                 break;
287             }
288             fileSize += buf.st_size;
289         } else {
290             list->PushBack(Utils::Strdup(filePath));
291         }
292     }
293 #ifdef __LITEOS_M__
294 #ifndef CONFIG_FT_MODE
295     OhosBmsCjsonHooksInit();
296 #endif
297 #endif
298     closedir(dir);
299     return fileSize;
300 }
301 
DeleteJsonFile(const char * bundleName,const char * randStr)302 void BundleUtil::DeleteJsonFile(const char *bundleName, const char *randStr)
303 {
304     if (bundleName == nullptr || randStr == nullptr) {
305         return;
306     }
307     char *bundleTmpJsonPathComp[] = {
308         const_cast<char *>(JSON_PATH), const_cast<char *>(bundleName), const_cast<char *>(randStr),
309         const_cast<char *>(JSON_SUFFIX)
310     };
311 
312     char *bundleTmpJsonPath = Strscat(bundleTmpJsonPathComp, sizeof(bundleTmpJsonPathComp) / sizeof(char *));
313     if (bundleTmpJsonPath == nullptr) {
314         return;
315     }
316 
317     if (IsFile(bundleTmpJsonPath)) {
318 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
319         BundleDaemonClient::GetInstance().RemoveFile(bundleTmpJsonPath);
320 #else
321         (void)unlink(bundleTmpJsonPath);
322 #endif
323         AdapterFree(bundleTmpJsonPath);
324         return;
325     }
326     AdapterFree(bundleTmpJsonPath);
327 
328     char *bundleJsonPathComp[] = {
329         const_cast<char *>(JSON_PATH), const_cast<char *>(bundleName), const_cast<char *>(JSON_SUFFIX)
330     };
331     char *bundleJsonPath = Strscat(bundleJsonPathComp, sizeof(bundleJsonPathComp) / sizeof(char *));
332     if (bundleJsonPath == nullptr) {
333         return;
334     }
335     if (IsFile(bundleJsonPath)) {
336 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
337         BundleDaemonClient::GetInstance().RemoveFile(bundleJsonPath);
338 #else
339         (void)unlink(bundleJsonPath);
340 #endif
341     }
342     AdapterFree(bundleJsonPath);
343 }
344 
Strscat(char * str[],uint32_t len)345 char *BundleUtil::Strscat(char *str[], uint32_t len)
346 {
347     int32_t strSize = 0;
348     for (uint32_t i = 0; i < len; i++) {
349         if (str[i] == nullptr) {
350             return nullptr;
351         }
352         strSize += strlen(str[i]);
353     }
354 
355     char *outStr = reinterpret_cast<char *>(AdapterMalloc((strSize + 1) * sizeof(char)));
356     if (outStr == nullptr) {
357         return nullptr;
358     }
359 
360     char *pos = outStr;
361     int32_t count = 0;
362     for (uint32_t i = 0; i < len; i++) {
363         int32_t size = strlen(str[i]);
364         if (memcpy_s(pos, strSize + 1 - count, str[i], size) != EOK) {
365             AdapterFree(outStr);
366             return nullptr;
367         }
368         count += size;
369         pos += size;
370     }
371     *pos = '\0';
372     return outStr;
373 }
374 
GetJsonStream(const char * path)375 cJSON *BundleUtil::GetJsonStream(const char *path)
376 {
377     struct stat fileInfo;
378     int32_t size = 0;
379 
380     if (!IsFile(path)) {
381 #ifdef APP_PLATFORM_WATCHGT
382         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] GetJsonStream IsFile fail");
383 #endif
384         return nullptr;
385     }
386 
387     if (stat(path, &fileInfo) != 0 || (size = fileInfo.st_size) <= 0) {
388 #ifdef APP_PLATFORM_WATCHGT
389         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] GetJsonStream path fail");
390 #endif
391         return nullptr;
392     }
393 #ifdef __LITEOS_M__
394 #ifndef CONFIG_FT_MODE
395     OhosBmsCjsonHooksInit();
396 #endif
397 #endif
398     if (size > MAX_JSON_SIZE) {
399 #ifdef APP_PLATFORM_WATCHGT
400         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] GetJsonStream size fail:%d", size);
401 #endif
402         return nullptr;
403     }
404 
405     int32_t fp = open(path, O_RDONLY, S_IREAD | S_IWRITE);
406     if (fp < 0) {
407 #ifdef APP_PLATFORM_WATCHGT
408         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] GetJsonStream open fail:%d", fp);
409 #endif
410         return nullptr;
411     }
412 
413     char *json = reinterpret_cast<char *>(AdapterMalloc(size));
414     if (json == nullptr) {
415         close(fp);
416 #ifdef APP_PLATFORM_WATCHGT
417         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] GetJsonStream AdapterMalloc fail");
418 #endif
419         return nullptr;
420     }
421 
422     if (read(fp, json, size) != size) {
423         AdapterFree(json);
424         close(fp);
425 #ifdef APP_PLATFORM_WATCHGT
426         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] GetJsonStream read fail");
427 #endif
428         return nullptr;
429     }
430     close(fp);
431 
432     cJSON *root = cJSON_Parse(json);
433     AdapterFree(json);
434     json = nullptr;
435     if (root == nullptr) {
436 #ifdef APP_PLATFORM_WATCHGT
437         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] cJSON_Parse fail");
438 #endif
439     }
440     return root;
441 }
442 
CheckBundleJsonIsValid(const char * bundleName,char ** codePath,char ** appId,int32_t & versionCode)443 bool BundleUtil::CheckBundleJsonIsValid(const char *bundleName, char **codePath, char **appId, int32_t &versionCode)
444 {
445     if (bundleName == nullptr || codePath == nullptr || appId == nullptr) {
446 #ifdef APP_PLATFORM_WATCHGT
447         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] CheckBundleJsonIsValid parameters are not valid");
448 #endif
449         return false;
450     }
451 
452     char bundleJsonPath[PATH_LENGTH] = { 0 };
453     if (sprintf_s(bundleJsonPath, PATH_LENGTH, "%s%s%s", JSON_PATH, bundleName, JSON_SUFFIX) < 0) {
454 #ifdef APP_PLATFORM_WATCHGT
455         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] failed to organize bundleJson data file path");
456 #endif
457         return false;
458     }
459 
460     cJSON *object = GetJsonStream(bundleJsonPath);
461     if (object == nullptr) {
462 #ifdef APP_PLATFORM_WATCHGT
463         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] failed to open json file");
464 #endif
465         return false;
466     }
467 
468     cJSON *item = cJSON_GetObjectItem(object, JSON_SUB_KEY_CODEPATH);
469     if (!cJSON_IsString(item)) {
470         cJSON_Delete(object);
471 #ifdef APP_PLATFORM_WATCHGT
472         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] result of parsing codePath is not a string");
473 #endif
474         return false;
475     }
476     *codePath = Utils::Strdup(item->valuestring);
477     if (*codePath == nullptr) {
478         cJSON_Delete(object);
479 #ifdef APP_PLATFORM_WATCHGT
480         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] parsed codePath is nullptr");
481 #endif
482         return false;
483     }
484     if (!IsDir(*codePath)) {
485         cJSON_Delete(object);
486 #ifdef APP_PLATFORM_WATCHGT
487         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] parsed codePath is not dir");
488 #endif
489         return false;
490     }
491     if (!EndWith(*codePath, bundleName)) {
492         cJSON_Delete(object);
493 #ifdef APP_PLATFORM_WATCHGT
494         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] parsed codePath is not valid");
495 #endif
496         return false;
497     }
498 
499     item = cJSON_GetObjectItem(object, JSON_SUB_KEY_APPID);
500     if (!cJSON_IsString(item)) {
501         cJSON_Delete(object);
502 #ifdef APP_PLATFORM_WATCHGT
503         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] result of parsinng appId is not a string");
504 #endif
505         return false;
506     }
507     *appId = Utils::Strdup(item->valuestring);
508     if (*appId == nullptr) {
509         cJSON_Delete(object);
510 #ifdef APP_PLATFORM_WATCHGT
511         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] parsed appId is null");
512 #endif
513         return false;
514     }
515 
516     item = cJSON_GetObjectItem(object, JSON_SUB_KEY_VERSIONCODE);
517     if (!cJSON_IsNumber(item)) {
518         cJSON_Delete(object);
519 #ifdef APP_PLATFORM_WATCHGT
520         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] result of parsinng versionCode is not a string");
521 #endif
522         return false;
523     }
524     versionCode = item->valueint;
525     if (versionCode < 0) {
526         cJSON_Delete(object);
527 #ifdef APP_PLATFORM_WATCHGT
528         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] parsed versionCode is not valid");
529 #endif
530         return false;
531     }
532 
533     cJSON_Delete(object);
534     return true;
535 }
536 
GetValueFromBundleJson(const char * bundleName,const char * key)537 char *BundleUtil::GetValueFromBundleJson(const char *bundleName, const char *key)
538 {
539     if (bundleName == nullptr || key == nullptr) {
540         return nullptr;
541     }
542 
543     char bundleJsonPath[PATH_LENGTH] = { 0 };
544     if (sprintf_s(bundleJsonPath, PATH_LENGTH, "%s%s%s", JSON_PATH, bundleName, JSON_SUFFIX) < 0) {
545         return nullptr;
546     }
547 
548     cJSON *object = GetJsonStream(bundleJsonPath);
549     if (object == nullptr) {
550         return nullptr;
551     }
552 
553     cJSON *item = cJSON_GetObjectItem(object, key);
554     if (!cJSON_IsString(item)) {
555         cJSON_Delete(object);
556         return nullptr;
557     }
558 
559     char *value = Utils::Strdup(item->valuestring);
560     cJSON_Delete(object);
561     return value;
562 }
563 
GetValueFromBundleJson(const char * bundleName,const char * key,int32_t defaultValue)564 int32_t BundleUtil::GetValueFromBundleJson(const char *bundleName, const char *key, int32_t defaultValue)
565 {
566     if (bundleName == nullptr || key == nullptr) {
567         return defaultValue;
568     }
569 
570     char bundleJsonPath[PATH_LENGTH] = { 0 };
571     if (sprintf_s(bundleJsonPath, PATH_LENGTH, "%s%s%s", JSON_PATH, bundleName, JSON_SUFFIX) < 0) {
572         return defaultValue;
573     }
574 
575     cJSON *object = GetJsonStream(bundleJsonPath);
576     if (object == nullptr) {
577         return defaultValue;
578     }
579 
580     cJSON *item = cJSON_GetObjectItem(object, key);
581     if (!cJSON_IsNumber(item)) {
582         cJSON_Delete(object);
583         return defaultValue;
584     }
585 
586     int32_t value = item->valueint;
587     cJSON_Delete(object);
588     return value;
589 }
590 
ConvertInstallRecordToJson(const InstallRecord & installRecord)591 cJSON *BundleUtil::ConvertInstallRecordToJson(const InstallRecord &installRecord)
592 {
593     cJSON *root = cJSON_CreateObject();
594     if (root == nullptr) {
595         return nullptr;
596     }
597 
598     if ((cJSON_AddStringToObject(root, JSON_SUB_KEY_PACKAGE, installRecord.bundleName) == nullptr) ||
599         (cJSON_AddStringToObject(root, JSON_SUB_KEY_APPID, installRecord.appId) == nullptr) ||
600 #ifdef APP_PLATFORM_WATCHGT
601 #ifdef BC_TRANS_ENABLE
602     (cJSON_AddStringToObject(root, JSON_SUB_KEY_JSENGINE_VERSION, installRecord.jsEngineVersion) == nullptr) ||
603     (cJSON_AddNumberToObject(root, JSON_SUB_KEY_TRANSFORM_RESULT, installRecord.transformResult) == nullptr) ||
604 #endif
605 #endif
606     (cJSON_AddNumberToObject(root, JSON_SUB_KEY_VERSIONCODE, installRecord.versionCode) == nullptr) ||
607 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
608     (cJSON_AddNumberToObject(root, JSON_SUB_KEY_UID, installRecord.uid) == nullptr) ||
609     (cJSON_AddNumberToObject(root, JSON_SUB_KEY_GID, installRecord.gid) == nullptr) ||
610 #endif
611     (cJSON_AddStringToObject(root, JSON_SUB_KEY_CODEPATH, installRecord.codePath) == nullptr)) {
612         cJSON_Delete(root);
613         return nullptr;
614     }
615     return root;
616 }
617 
CreateRandStr(char * str,uint32_t len)618 void BundleUtil::CreateRandStr(char *str, uint32_t len)
619 {
620     if (str == nullptr) {
621         return;
622     }
623 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
624     srand(time(NULL));
625 #else
626     srand(LOS_TickCountGet());
627 #endif
628     uint32_t i;
629     for (i = 0; i < len - 1; ++i) {
630         switch ((rand() % NUM_OF_TYPE)) {
631             case 0:
632                 str[i] = 'A' + rand() % MAX_CHARACTER_VALUE;
633                 break;
634             case 1:
635                 str[i] = 'a' + rand() % MAX_CHARACTER_VALUE;
636                 break;
637             default:
638                 str[i] = '0' + rand() % MAX_SINGLE_DIGIT_VALUE;
639                 break;
640         }
641     }
642     str[i] = '\0';
643 }
644 
645 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
ObtainUidAndGidJson(bool flag)646 cJSON *BundleUtil::ObtainUidAndGidJson(bool flag)
647 {
648     std::string uidJsonPath = std::string(JSON_PATH) + UID_GID_MAP + JSON_SUFFIX;
649     cJSON *object = BundleUtil::GetJsonStream(uidJsonPath.c_str());
650     if ((object != nullptr) || (!flag)) {
651         return object;
652     }
653 
654     object = cJSON_CreateObject();
655     if (object == nullptr) {
656         return nullptr;
657     }
658     cJSON *size = cJSON_CreateNumber(0);
659     if (size == nullptr) {
660         cJSON_Delete(object);
661         return nullptr;
662     }
663     if (!cJSON_AddItemToObject(object, PROFILE_KEY_UID_SIZE, size)) {
664         cJSON_Delete(size);
665         cJSON_Delete(object);
666         return nullptr;
667     }
668     cJSON *uids = cJSON_AddArrayToObject(object, PROFILE_KEY_UID_AND_GID);
669     if (uids == nullptr) {
670         cJSON_Delete(object);
671         return nullptr;
672     }
673     return object;
674 }
675 
AddUidAndGidInfo(const InstallRecord & installRecord,cJSON * size,cJSON * uids)676 bool BundleUtil::AddUidAndGidInfo(const InstallRecord &installRecord, cJSON *size, cJSON *uids)
677 {
678     if ((size == nullptr) || (uids == nullptr)) {
679         return false;
680     }
681     cJSON_SetNumberValue(size, size->valueint + 1);
682     cJSON *uid = cJSON_CreateObject();
683     if (uid == nullptr) {
684         return false;
685     }
686     if ((cJSON_AddStringToObject(uid, JSON_SUB_KEY_PACKAGE, installRecord.bundleName) == nullptr) ||
687         (cJSON_AddNumberToObject(uid, JSON_SUB_KEY_UID, installRecord.uid) == nullptr) ||
688         (cJSON_AddNumberToObject(uid, JSON_SUB_KEY_GID, installRecord.gid) == nullptr)) {
689         cJSON_Delete(uid);
690         return false;
691     }
692     if (!cJSON_AddItemToArray(uids, uid)) {
693         cJSON_Delete(uid);
694         return false;
695     }
696     return true;
697 }
698 
ConvertUidAndGidToJson(const InstallRecord & installRecord)699 cJSON *BundleUtil::ConvertUidAndGidToJson(const InstallRecord &installRecord)
700 {
701     if (installRecord.bundleName == nullptr) {
702         return nullptr;
703     }
704 
705     cJSON *object = ObtainUidAndGidJson(true);
706     if (object == nullptr) {
707         return nullptr;
708     }
709 
710     cJSON *size = cJSON_GetObjectItemCaseSensitive(object, PROFILE_KEY_UID_SIZE);
711     if (!cJSON_IsNumber(size)) {
712         cJSON_Delete(object);
713         return nullptr;
714     }
715     cJSON *uids = cJSON_GetObjectItemCaseSensitive(object, PROFILE_KEY_UID_AND_GID);
716     if (!cJSON_IsArray(uids)) {
717         cJSON_Delete(object);
718         return nullptr;
719     }
720 
721     cJSON *item = nullptr;
722     cJSON_ArrayForEach(item, uids) {
723         cJSON *innerBundleName = cJSON_GetObjectItemCaseSensitive(item, JSON_SUB_KEY_PACKAGE);
724         if ((cJSON_IsString(innerBundleName)) && (innerBundleName->valuestring != nullptr)) {
725             if (strcmp(innerBundleName->valuestring, installRecord.bundleName) == 0) {
726                 return object;
727             }
728         }
729     }
730 
731     if (!AddUidAndGidInfo(installRecord, size, uids)) {
732         cJSON_Delete(object);
733         return nullptr;
734     }
735 
736     return object;
737 }
738 
DeleteInnerUidInfoFromUidArray(const char * bundleName,cJSON * size,cJSON * uids)739 bool BundleUtil::DeleteInnerUidInfoFromUidArray(const char *bundleName, cJSON *size, cJSON *uids)
740 {
741     if ((size == nullptr) || (uids == nullptr) || (bundleName == nullptr)) {
742         return false;
743     }
744     cJSON *uid = nullptr;
745     int32_t index = -1;
746     bool isFound = false;
747     cJSON_ArrayForEach(uid, uids) {
748         index++;
749         cJSON *innerBundleName = cJSON_GetObjectItemCaseSensitive(uid, JSON_SUB_KEY_PACKAGE);
750         if ((cJSON_IsString(innerBundleName)) && (innerBundleName->valuestring != nullptr)) {
751             if (strcmp(innerBundleName->valuestring, bundleName) == 0) {
752                 isFound = true;
753                 break;
754             }
755         }
756     }
757     if (isFound) {
758         cJSON_DeleteItemFromArray(uids, index);
759         cJSON_SetNumberValue(size, size->valueint - 1);
760     }
761     return true;
762 }
763 
DeleteUidInfoFromJson(const char * bundleName)764 bool BundleUtil::DeleteUidInfoFromJson(const char *bundleName)
765 {
766     cJSON *object = ObtainUidAndGidJson(false);
767     if (object == nullptr) {
768         return false;
769     }
770 
771     cJSON *size = cJSON_GetObjectItemCaseSensitive(object, PROFILE_KEY_UID_SIZE);
772     if (!cJSON_IsNumber(size)) {
773         cJSON_Delete(object);
774         return false;
775     }
776     cJSON *uids = cJSON_GetObjectItemCaseSensitive(object, PROFILE_KEY_UID_AND_GID);
777     if (!cJSON_IsArray(uids)) {
778         cJSON_Delete(object);
779         return false;
780     }
781     if (!DeleteInnerUidInfoFromUidArray(bundleName, size, uids)) {
782         cJSON_Delete(object);
783         return false;
784     }
785 
786     std::string uidJsonPath = std::string(JSON_PATH) + UID_GID_MAP + JSON_SUFFIX;
787     if (size->valueint == 0) {
788         BundleDaemonClient::GetInstance().RemoveFile(uidJsonPath.c_str());
789     } else {
790         char *out = cJSON_Print(object);
791         if (out == nullptr) {
792             cJSON_Delete(object);
793             return false;
794         }
795         BundleDaemonClient::GetInstance().StoreContentToFile(uidJsonPath.c_str(), out, strlen(out) + 1);
796         cJSON_free(out);
797     }
798 
799     cJSON_Delete(object);
800     return true;
801 }
802 #else
MkDirs(const char * dir)803 bool BundleUtil::MkDirs(const char *dir)
804 {
805     if (IsDir(dir)) {
806         return true;
807     }
808     if (strlen(dir) > PATH_LENGTH) {
809 #ifdef APP_PLATFORM_WATCHGT
810         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] MkDirs failed, path is too long");
811 #endif
812         return false;
813     }
814     int32_t len = strlen(dir);
815     char *rootDir = nullptr;
816     bool isRootDirExists = true;
817     for (int32_t i = 1; i < len; i++) {
818         if (dir[i] != '/') {
819             continue;
820         }
821         rootDir = GetRootDir(dir, i);
822         if (rootDir == nullptr) {
823 #ifdef APP_PLATFORM_WATCHGT
824             HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] MkDirs failed, rootDir is null");
825 #endif
826             return false;
827         }
828         if (isRootDirExists) {
829             if (IsDir(rootDir)) {
830                 UI_Free(rootDir);
831                 rootDir = nullptr;
832                 continue;
833             }
834             isRootDirExists = false;
835         }
836         if (mkdir(rootDir, S_IREAD | S_IWRITE) < 0) {
837             UI_Free(rootDir);
838 #ifdef APP_PLATFORM_WATCHGT
839             HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] make rootDir failed");
840 #endif
841             return false;
842         }
843         UI_Free(rootDir);
844         rootDir = nullptr;
845     }
846     return (mkdir(dir, S_IREAD | S_IWRITE) < 0) ? false : true;
847 }
848 
RemoveDir(const char * path)849 bool BundleUtil::RemoveDir(const char *path)
850 {
851     if (!IsDir(path)) {
852         (void) unlink(path);
853         return true;
854     }
855 
856     List<char *>* list = new (std::nothrow)List<char *>();
857     if (list == nullptr) {
858 #ifdef APP_PLATFORM_WATCHGT
859         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] RemoveDir failed, list is null");
860 #endif
861         return false;
862     }
863     list->PushFront(Utils::Strdup(path));
864     while (!list->IsEmpty()) {
865         char *curPath = list->Front();
866         if (curPath == nullptr) {
867             break;
868         }
869         if (CheckDirIsEmpty(curPath, list)) {
870             list->PopFront();
871             if (rmdir(curPath) < 0) {
872                 AdapterFree(curPath);
873                 break;
874             }
875             AdapterFree(curPath);
876         }
877     }
878 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
879     for (auto node = list->Begin(); node != list->End(); node = node->next_) {
880         AdapterFree(node->value_);
881     }
882 #endif
883     if (!list->IsEmpty()) {
884         delete list;
885 #ifdef APP_PLATFORM_WATCHGT
886         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] After delete, file is still not empty");
887 #endif
888         return false;
889     }
890 
891     delete list;
892     return true;
893 }
894 
RenameDir(const char * oldDir,const char * newDir)895 bool BundleUtil::RenameDir(const char *oldDir, const char *newDir)
896 {
897     if (oldDir == nullptr || newDir == nullptr) {
898         return false;
899     }
900 
901     if (IsDir(newDir) && !RemoveDir(newDir)) {
902         return false;
903     }
904 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
905     if (frename(oldDir, newDir) != 0) {
906         return false;
907     }
908 #else
909     if (rename(oldDir, newDir) != 0) {
910         return false;
911     }
912 #endif
913     return true;
914 }
915 
RenameFile(const char * oldFile,const char * newFile)916 bool BundleUtil::RenameFile(const char *oldFile, const char *newFile)
917 {
918     if (oldFile == nullptr || newFile == nullptr) {
919         return false;
920     }
921 
922     if (IsFile(newFile) && unlink(newFile) < 0) {
923         return false;
924     }
925 
926 #ifdef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
927     if (frename(oldFile, newFile) != 0) {
928         return false;
929     }
930 #else
931     if (rename(oldFile, newFile) != 0) {
932         return false;
933     }
934 #endif
935     return true;
936 }
937 
GetRootDir(const char * dir,int32_t index)938 char *BundleUtil::GetRootDir(const char *dir, int32_t index)
939 {
940     char *rootDir = reinterpret_cast<char *>(UI_Malloc((index + 1) * sizeof(char)));
941     if (rootDir == nullptr) {
942         return nullptr;
943     }
944     errno_t err = strncpy_s(rootDir, index + 1, dir, index);
945     if (err != EOK) {
946         UI_Free(rootDir);
947         return nullptr;
948     }
949     return rootDir;
950 }
951 
CheckDirIsEmpty(const char * dirPath,List<char * > * list)952 bool BundleUtil::CheckDirIsEmpty(const char *dirPath, List<char *>* list)
953 {
954 #ifndef OHOS_APPEXECFWK_BMS_BUNDLEMANAGER
955     RefreshAllServiceTimeStamp();
956 #endif
957     DIR *dir = nullptr;
958     if ((dir = opendir(dirPath)) == nullptr) {
959         return false;
960     }
961     bool isEmptyDir = true;
962     dirent *dp = nullptr;
963     char filePath[PATH_LENGTH] = { 0 };
964     while ((dp = readdir(dir)) != nullptr) {
965         if ((strcmp(dp->d_name, ".") == 0) || (strcmp(dp->d_name, "..")) == 0) {
966             continue;
967         }
968 
969         if (memset_s(filePath, PATH_LENGTH, 0, PATH_LENGTH) != EOK) {
970             continue;
971         }
972 
973         if (sprintf_s(filePath, PATH_LENGTH, "%s/%s", dirPath, dp->d_name) < 0) {
974             continue;
975         }
976 
977         if (IsDir(filePath)) {
978             list->PushFront(Utils::Strdup(filePath));
979             isEmptyDir = false;
980         } else {
981             (void) unlink(filePath);
982         }
983     }
984     closedir(dir);
985     return isEmptyDir;
986 }
StoreJsonContentToFile(const char * packageJson,const cJSON * object)987 bool BundleUtil::StoreJsonContentToFile(const char *packageJson, const cJSON *object)
988 {
989     if (object == nullptr) {
990 #ifdef APP_PLATFORM_WATCHGT
991         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] Json data object is null");
992 #endif
993         return false;
994     }
995 
996     char *out = cJSON_Print(object);
997     if (out == nullptr) {
998 #ifdef APP_PLATFORM_WATCHGT
999         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] turn Json data to char sequence failed");
1000 #endif
1001         return false;
1002     }
1003 
1004     if (!CheckRealPath(packageJson)) {
1005         cJSON_free(out);
1006 #ifdef APP_PLATFORM_WATCHGT
1007         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] Json file path doest not exist");
1008 #endif
1009         return false;
1010     }
1011 
1012     if (IsFile(packageJson) && unlink(packageJson) < 0) {
1013         cJSON_free(out);
1014 #ifdef APP_PLATFORM_WATCHGT
1015         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] Json file path is invalid");
1016 #endif
1017         return false;
1018     }
1019 
1020     int32_t fp = open(packageJson, O_RDWR | O_CREAT, S_IREAD | S_IWRITE);
1021     if (fp < 0) {
1022         cJSON_free(out);
1023 #ifdef APP_PLATFORM_WATCHGT
1024         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] open Json file failed");
1025 #endif
1026         return false;
1027     }
1028 
1029     if (write(fp, out, strlen(out)) != strlen(out)) {
1030         cJSON_free(out);
1031         close(fp);
1032 #ifdef APP_PLATFORM_WATCHGT
1033         HILOG_ERROR(HILOG_MODULE_AAFWK, "[BMS] write to Json file failed");
1034 #endif
1035         return false;
1036     }
1037 
1038     cJSON_free(out);
1039     close(fp);
1040     return true;
1041 }
1042 
FreeStrArrayMemory(char ** pointer,uint32_t len)1043 void BundleUtil::FreeStrArrayMemory(char **pointer, uint32_t len)
1044 {
1045     if (len != 0 && pointer != nullptr) {
1046         for (uint32_t i = 0; i < len; i++) {
1047             AdapterFree(*(pointer + i));
1048         }
1049         AdapterFree(pointer);
1050     }
1051 }
1052 #endif
1053 } // namespace OHOS